{"owner":"gitroomhq","repo":"postiz-app","hasSkills":true,"totalSkillsCount":6,"totalTokensCount":3112,"categories":["anthropic-skill","claude-rule","copilot-instructions"],"hasMcp":false,"mcpConfig":null,"found":["apps/commands/nest-cli.json","apps/commands/tsconfig.json","apps/commands/package.json","apps/commands/tsconfig.build.json","CLAUDE.md",".github/copilot-instructions.md"],"skills":{"apps/commands/nest-cli.json":"{\n  \"$schema\": \"https://json.schemastore.org/nest-cli\",\n  \"collection\": \"@nestjs/schematics\",\n  \"monorepo\": false,\n  \"sourceRoot\": \"src\",\n  \"entryFile\": \"../../dist/commands/apps/commands/src/main\",\n  \"language\": \"ts\",\n  \"generateOptions\": {\n    \"spec\": false\n  },\n  \"compilerOptions\": {\n    \"manualRestart\": true,\n    \"tsConfigPath\": \"./tsconfig.build.json\",\n    \"webpack\": false,\n    \"deleteOutDir\": true,\n    \"assets\": [],\n    \"watchAssets\": false,\n    \"plugins\": []\n  }\n}\n","apps/commands/tsconfig.json":"{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"es2017\",\n    \"sourceMap\": true,\n    \"esModuleInterop\": true\n  }\n}\n","apps/commands/package.json":"{\n  \"name\": \"postiz-command\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"scripts\": {\n    \"dev\": \"dotenv -e ../../.env -- nest start --watch --entryFile=./apps/command/src/main\",\n    \"build\": \"cross-env NODE_ENV=production nest build\",\n    \"start\": \"node ./dist/apps/command/src/main.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}\n","apps/commands/tsconfig.build.json":"{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"],\n  \"compilerOptions\": {\n    \"module\": \"CommonJS\",\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"ES2021\",\n    \"sourceMap\": true,\n    \"incremental\": true,\n    \"skipLibCheck\": true,\n    \"strictNullChecks\": false,\n    \"noImplicitAny\": false,\n    \"strictBindCallApply\": false,\n    \"forceConsistentCasingInFileNames\": false,\n    \"noFallthroughCasesInSwitch\": false,\n    \"outDir\": \"./dist\"\n  }\n}\n","CLAUDE.md":"This project is Postiz, a tool to schedule social media and chat posts to 28+ channels.\nYou can add posts to the calendar, they will be added into a workflow and posted at the right time.\nYou can find things like:\n- Schedule posts\n- Calendar view\n- Analytics\n- Team management\n- Media library\n\nThis project is a monorepo with a root only package.json of dependencies.\nMade with PNPM.\nWe have 3 important folders\n\n- apps/backend - this is where the API code is (NESTJS)\n- apps/orchestrator - this is temporal, it's for background jobs (NESTJS) it contains all the workflows and activities\n- apps/frontend - this is the code of the frontend (Vite ReactJS)\n- /libraries contains a lot of services shared between backend and orchestrator and frontend components.\n\nWe are using only pnpm, don't use any other dependency manager.\nNever install frontend components from npmjs, focus on writing native components.\n\nThe project uses tailwind 3, before writing any component look at:\n- /apps/frontend/src/app/colors.scss\n- /apps/frontend/src/app/global.scss\n- /apps/frontend/tailwind.config.js\n\nAll the --color-custom* are deprecated, don't use them.\n\nAnd check other components in the system before to get the right design.\n\nWhen working on the backend we need to pass the 3 layers:\nDTO >> Controller >> Service >> Repository (no shortcuts)\nIn some cases we will have\nDTO >> Controller >> Manager >> Service >> Repository.\n\nMost of the server logic should be inside of libs/server.\nThe backend repository is mostly used to write controller, and import files from libs.server.\n\nFor the frontend follow this:\n- Many of the UI components lives in /apps/frontend/src/components/ui\n- Routing is in /apps/frontend/src/app\n- Components are in /apps/frontend/src/components\n- always use SWR to fetch stuff, and use \"useFetch\" hook from /libraries/helpers/src/utils/custom.fetch.tsx\n\nWhen using SWR, each one have to be in a separate hook and must comply with react-hooks/rules-of-hooks, never put eslint-disable-next-line on it.\n\nIt means that this is valid:\nconst useCommunity = () => {\n   return useSWR....\n}\n\nThis is not valid:\nconst useCommunity = () => {\n  return {\n    communities: () => useSWR<CommunitiesListResponse>(\"communities\", getCommunities),\n    providers: () => useSWR<ProvidersListResponse>(\"providers\", getProviders),\n  };\n}\n\n- Linting of the project can run only from the root.\n- Use only pnpm.\n- Never use RAW SQL queries, always use Prisma.\n- The system is in production with many users, if you want to change something, you need to be sure that you are not breaking anything for existing users and a migration might be needed\n- Whenever you generate a PR, PR description, or similar, **always** follow the PR Template (.github/PULL_REQUEST_TEMPLATE.md)\n- Every PR description **must** contain a `# QA` section with real, numbered steps a reviewer can follow to verify the change (setup, action, expected result), written so they can be run without asking the author anything. This is not optional and applies to humans and agents alike, including one-line fixes. The section is extracted verbatim and shown on the review board, so:\n  - Use the exact heading `# QA` (`# Testing`, `# Test plan`, `# How to test`, `# How to verify`, `# Verification`, `# Steps to test` and `# Manual testing` are also recognised, but prefer `# QA`). The whole heading must match, so something like `## Testing philosophy` is not picked up.\n  - Never leave the template placeholder in place, and never write `N/A`, `TBD`, `todo`, `none` or a bare empty checkbox as the whole section - those all count as no QA at all and the board will show the PR as missing testing notes.\n  - Steps inside a fenced code block are ignored, so keep them as plain numbered lines. Write each step as a numbered checkbox (`1. [ ] step`) so a reviewer can tick it off while working through it - the numbering is what the board extracts, the checkbox is for the reviewer.\n- Every PR description **must** answer `# What kind of change does this PR introduce?` with actual detail, not just a category. `Bug fix.` / `Feature.` on its own is not acceptable. State the type, the area it touches (backend, frontend, orchestrator, a specific provider or screen), and in one to three sentences what concretely changed and where - the key function, endpoint, file or field - plus what deliberately stayed the same. A reader should understand the change from this section alone, without opening the diff.\n- Avoid as much as possible creating new files with pure logic of algorithms, it's usually wrong\n- When you write code, make sure that what you add looks like something similar somewhere else in the code, don't make weird patterns\n- When you finished running, run another agents that matches the new code with the existing system code, to see that it looks similar and is not a weird pattern.\n- Workflows files can never be changed if they are already in origin/main, because changing a workflow will fail all its activities, instead create a new workflow with the version, and everywhere the workflow being called, change it to the new workflow version.\n- Workflows activities parameters cannot be changed, as it will break the workflow, if we need to change the parameters, if we need to change the parameters, we need to create a new activity with the new parameters, and then create a new workflow that uses the new activity.\n- Code must always be generic, there can't be a way that a specific logic, let's say facebook or instagram, appear in a file that use a generic logic, instead, we need to edit the interface of the provider, add another function, and then generically call it from the generic code, and then implement the specific logic in the provider implementation. we can't have something like if(facebookProvider) {} inside a non facebook provider file.\n- Before adding a field to a shared repository/service `select` or changing a shared method's return shape, grep for all its consumers (frontend, public API, MCP/agent tools, orchestrator, webhooks) and confirm the change is intended for each.\n- Exposing a stored field to a new external surface (public API, MCP, webhooks) is a data-exposure decision — ask first, and check what existing production rows hold for that column before shipping it.\n- Never silently change the meaning or format of a value persisted in an existing DB column; that affects every reader and all historical rows, so ask first. \n- Never return a raw Prisma row from a model that holds credentials (`Integration`, `User` and similar) in a controller response. Repository writes on those models must use a `select` with only the fields the caller needs (like `setTimes` with `select: { id: true }`), or the controller returns nothing. This applies even where nearby code looks different.\n- Be extra careful with code invoked by webhooks of external systems (Stripe, RevenueCat and other payment providers), including everything they call down the stack (e.g. `SubscriptionService.createOrUpdateSubscription`, `modifySubscription`, `deleteSubscription`). That code must not throw exceptions: never add a `throw`, and wrap any call that can fail (DB, provider API) so a failure is caught and logged instead of propagating. A webhook that throws leaves billing state half-applied for a paying customer.\n",".github/copilot-instructions.md":"\n# Copilot Coding Agent Instructions for Postiz\n\n## Project Architecture\n- Monorepo managed by NX, with apps in `apps/` and shared code in `libraries/`.\n- Main services: `frontend` (Next.js), `backend` (NestJS), `cron`, `commands`, `extension`, `sdk`, and `workers`.\n- Data layer uses Prisma ORM (`libraries/nestjs-libraries/src/database/prisma/schema.prisma`) with PostgreSQL as the default database.\n- Redis (BullMQ) is used for queues and caching.\n- Email notifications via Resend.\n- Social login integrations (Instagram, Facebook) and Make.com/N8N integrations.\n\n## Developer Workflows\n- Use Node.js 20.17.0 and pnpm 8+.\n- Install dependencies: `pnpm install`\n- Build all apps: `pnpm run build`\n- Run all apps in dev mode: `pnpm run dev`\n- Test: `pnpm test` (Jest, coverage enabled)\n- Individual app scripts are in each app's `package.json` (e.g., `pnpm --filter ./apps/backend run dev`).\n- Prisma DB commands: `pnpm run prisma-generate`, `pnpm run prisma-db-push`, `pnpm run prisma-reset`.\n- Docker: `docker compose -f ./docker-compose.dev.yaml up -d`\n\n## Conventions & Patterns\n- Use conventional commits (`feat:`, `fix:`, `chore:`).\n- PRs should include clear descriptions, related issue links, and UI screenshots/GIFs if relevant.\n- Comments are required for complex logic.\n- Shared code lives in `libraries/` (e.g., helpers, React shared libraries, NestJS modules).\n- Environment variables are managed via `.env` and referenced in Docker and scripts.\n- Make sure to keep the `.env.example` file updated with new environment variables.\n\n## Integration Points\n- External APIs: Social media (Instagram, Facebook), Make.com, N8N, Resend, Stripe, etc.\n- SDK (`apps/sdk`) provides programmatic access to Postiz features.\n- Extension (`apps/extension`) is built with Vite, React, TypeScript, and Tailwind CSS.\n\n## Key Files & Directories\n- `apps/` — Main services and applications\n- `libraries/` — Shared code and modules\n- `docker-compose.dev.yaml` — Local development Docker setup\n- `.env` — Environment configuration\n- `jest.config.ts` — Test configuration\n- `pnpm-workspace.yaml` — Workspace package management\n- `README.md` — General project overview\n- `libraries/nestjs-libraries/src/database/prisma/schema.prisma` — Database schema\n\n## Documentation\n- Main docs: https://docs.postiz.com/\n- Developer guide: https://docs.postiz.com/developer-guide\n- Public API: https://docs.postiz.com/public-api\n\n---\n\n# Logs\n\n- Where logs are used, ensure Sentry is imported using `import * as Sentry from \"@sentry/nextjs\"`\n- Enable logging in Sentry using `Sentry.init({ enableLogs: true })`\n- Reference the logger using `const { logger } = Sentry`\n- Sentry offers a `consoleLoggingIntegration` that can be used to log specific console error types automatically without instrumenting the individual logger calls\n\n## Configuration\n\nThe Sentry initialization needs to be updated to enable the logs feature.\n\n### Baseline\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n\n  enableLogs: true,\n});\n```\n\n### Logger Integration\n\n```javascript\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n  integrations: [\n    // send console.log, console.error, and console.warn calls as logs to Sentry\n    Sentry.consoleLoggingIntegration({ levels: [\"log\", \"error\", \"warn\"] }),\n  ],\n});\n```\n\n## Logger Examples\n\n`logger.fmt` is a template literal function that should be used to bring variables into the structured logs.\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nconst { logger } = Sentry;\n\nlogger.trace(\"Starting database connection\", { database: \"users\" });\nlogger.debug(logger.fmt`Cache miss for user: ${userId}`);\nlogger.info(\"Updated profile\", { profileId: 345 });\nlogger.warn(\"Rate limit reached for endpoint\", {\n  endpoint: \"/api/results/\",\n  isEnterprise: false,\n});\nlogger.error(\"Failed to process payment\", {\n  orderId: \"order_123\",\n  amount: 99.99,\n});\nlogger.fatal(\"Database connection pool exhausted\", {\n  database: \"users\",\n  activeConnections: 100,\n});\n```\n\n---\n\nFor questions or unclear conventions, check the main README or ask for clarification in your PR description.\n\n"},"files":{"apps/commands/nest-cli.json":"{\n  \"$schema\": \"https://json.schemastore.org/nest-cli\",\n  \"collection\": \"@nestjs/schematics\",\n  \"monorepo\": false,\n  \"sourceRoot\": \"src\",\n  \"entryFile\": \"../../dist/commands/apps/commands/src/main\",\n  \"language\": \"ts\",\n  \"generateOptions\": {\n    \"spec\": false\n  },\n  \"compilerOptions\": {\n    \"manualRestart\": true,\n    \"tsConfigPath\": \"./tsconfig.build.json\",\n    \"webpack\": false,\n    \"deleteOutDir\": true,\n    \"assets\": [],\n    \"watchAssets\": false,\n    \"plugins\": []\n  }\n}\n","apps/commands/tsconfig.json":"{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"es2017\",\n    \"sourceMap\": true,\n    \"esModuleInterop\": true\n  }\n}\n","apps/commands/package.json":"{\n  \"name\": \"postiz-command\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"scripts\": {\n    \"dev\": \"dotenv -e ../../.env -- nest start --watch --entryFile=./apps/command/src/main\",\n    \"build\": \"cross-env NODE_ENV=production nest build\",\n    \"start\": \"node ./dist/apps/command/src/main.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}\n","apps/commands/tsconfig.build.json":"{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"],\n  \"compilerOptions\": {\n    \"module\": \"CommonJS\",\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"ES2021\",\n    \"sourceMap\": true,\n    \"incremental\": true,\n    \"skipLibCheck\": true,\n    \"strictNullChecks\": false,\n    \"noImplicitAny\": false,\n    \"strictBindCallApply\": false,\n    \"forceConsistentCasingInFileNames\": false,\n    \"noFallthroughCasesInSwitch\": false,\n    \"outDir\": \"./dist\"\n  }\n}\n","CLAUDE.md":"This project is Postiz, a tool to schedule social media and chat posts to 28+ channels.\nYou can add posts to the calendar, they will be added into a workflow and posted at the right time.\nYou can find things like:\n- Schedule posts\n- Calendar view\n- Analytics\n- Team management\n- Media library\n\nThis project is a monorepo with a root only package.json of dependencies.\nMade with PNPM.\nWe have 3 important folders\n\n- apps/backend - this is where the API code is (NESTJS)\n- apps/orchestrator - this is temporal, it's for background jobs (NESTJS) it contains all the workflows and activities\n- apps/frontend - this is the code of the frontend (Vite ReactJS)\n- /libraries contains a lot of services shared between backend and orchestrator and frontend components.\n\nWe are using only pnpm, don't use any other dependency manager.\nNever install frontend components from npmjs, focus on writing native components.\n\nThe project uses tailwind 3, before writing any component look at:\n- /apps/frontend/src/app/colors.scss\n- /apps/frontend/src/app/global.scss\n- /apps/frontend/tailwind.config.js\n\nAll the --color-custom* are deprecated, don't use them.\n\nAnd check other components in the system before to get the right design.\n\nWhen working on the backend we need to pass the 3 layers:\nDTO >> Controller >> Service >> Repository (no shortcuts)\nIn some cases we will have\nDTO >> Controller >> Manager >> Service >> Repository.\n\nMost of the server logic should be inside of libs/server.\nThe backend repository is mostly used to write controller, and import files from libs.server.\n\nFor the frontend follow this:\n- Many of the UI components lives in /apps/frontend/src/components/ui\n- Routing is in /apps/frontend/src/app\n- Components are in /apps/frontend/src/components\n- always use SWR to fetch stuff, and use \"useFetch\" hook from /libraries/helpers/src/utils/custom.fetch.tsx\n\nWhen using SWR, each one have to be in a separate hook and must comply with react-hooks/rules-of-hooks, never put eslint-disable-next-line on it.\n\nIt means that this is valid:\nconst useCommunity = () => {\n   return useSWR....\n}\n\nThis is not valid:\nconst useCommunity = () => {\n  return {\n    communities: () => useSWR<CommunitiesListResponse>(\"communities\", getCommunities),\n    providers: () => useSWR<ProvidersListResponse>(\"providers\", getProviders),\n  };\n}\n\n- Linting of the project can run only from the root.\n- Use only pnpm.\n- Never use RAW SQL queries, always use Prisma.\n- The system is in production with many users, if you want to change something, you need to be sure that you are not breaking anything for existing users and a migration might be needed\n- Whenever you generate a PR, PR description, or similar, **always** follow the PR Template (.github/PULL_REQUEST_TEMPLATE.md)\n- Every PR description **must** contain a `# QA` section with real, numbered steps a reviewer can follow to verify the change (setup, action, expected result), written so they can be run without asking the author anything. This is not optional and applies to humans and agents alike, including one-line fixes. The section is extracted verbatim and shown on the review board, so:\n  - Use the exact heading `# QA` (`# Testing`, `# Test plan`, `# How to test`, `# How to verify`, `# Verification`, `# Steps to test` and `# Manual testing` are also recognised, but prefer `# QA`). The whole heading must match, so something like `## Testing philosophy` is not picked up.\n  - Never leave the template placeholder in place, and never write `N/A`, `TBD`, `todo`, `none` or a bare empty checkbox as the whole section - those all count as no QA at all and the board will show the PR as missing testing notes.\n  - Steps inside a fenced code block are ignored, so keep them as plain numbered lines. Write each step as a numbered checkbox (`1. [ ] step`) so a reviewer can tick it off while working through it - the numbering is what the board extracts, the checkbox is for the reviewer.\n- Every PR description **must** answer `# What kind of change does this PR introduce?` with actual detail, not just a category. `Bug fix.` / `Feature.` on its own is not acceptable. State the type, the area it touches (backend, frontend, orchestrator, a specific provider or screen), and in one to three sentences what concretely changed and where - the key function, endpoint, file or field - plus what deliberately stayed the same. A reader should understand the change from this section alone, without opening the diff.\n- Avoid as much as possible creating new files with pure logic of algorithms, it's usually wrong\n- When you write code, make sure that what you add looks like something similar somewhere else in the code, don't make weird patterns\n- When you finished running, run another agents that matches the new code with the existing system code, to see that it looks similar and is not a weird pattern.\n- Workflows files can never be changed if they are already in origin/main, because changing a workflow will fail all its activities, instead create a new workflow with the version, and everywhere the workflow being called, change it to the new workflow version.\n- Workflows activities parameters cannot be changed, as it will break the workflow, if we need to change the parameters, if we need to change the parameters, we need to create a new activity with the new parameters, and then create a new workflow that uses the new activity.\n- Code must always be generic, there can't be a way that a specific logic, let's say facebook or instagram, appear in a file that use a generic logic, instead, we need to edit the interface of the provider, add another function, and then generically call it from the generic code, and then implement the specific logic in the provider implementation. we can't have something like if(facebookProvider) {} inside a non facebook provider file.\n- Before adding a field to a shared repository/service `select` or changing a shared method's return shape, grep for all its consumers (frontend, public API, MCP/agent tools, orchestrator, webhooks) and confirm the change is intended for each.\n- Exposing a stored field to a new external surface (public API, MCP, webhooks) is a data-exposure decision — ask first, and check what existing production rows hold for that column before shipping it.\n- Never silently change the meaning or format of a value persisted in an existing DB column; that affects every reader and all historical rows, so ask first. \n- Never return a raw Prisma row from a model that holds credentials (`Integration`, `User` and similar) in a controller response. Repository writes on those models must use a `select` with only the fields the caller needs (like `setTimes` with `select: { id: true }`), or the controller returns nothing. This applies even where nearby code looks different.\n- Be extra careful with code invoked by webhooks of external systems (Stripe, RevenueCat and other payment providers), including everything they call down the stack (e.g. `SubscriptionService.createOrUpdateSubscription`, `modifySubscription`, `deleteSubscription`). That code must not throw exceptions: never add a `throw`, and wrap any call that can fail (DB, provider API) so a failure is caught and logged instead of propagating. A webhook that throws leaves billing state half-applied for a paying customer.\n",".github/copilot-instructions.md":"\n# Copilot Coding Agent Instructions for Postiz\n\n## Project Architecture\n- Monorepo managed by NX, with apps in `apps/` and shared code in `libraries/`.\n- Main services: `frontend` (Next.js), `backend` (NestJS), `cron`, `commands`, `extension`, `sdk`, and `workers`.\n- Data layer uses Prisma ORM (`libraries/nestjs-libraries/src/database/prisma/schema.prisma`) with PostgreSQL as the default database.\n- Redis (BullMQ) is used for queues and caching.\n- Email notifications via Resend.\n- Social login integrations (Instagram, Facebook) and Make.com/N8N integrations.\n\n## Developer Workflows\n- Use Node.js 20.17.0 and pnpm 8+.\n- Install dependencies: `pnpm install`\n- Build all apps: `pnpm run build`\n- Run all apps in dev mode: `pnpm run dev`\n- Test: `pnpm test` (Jest, coverage enabled)\n- Individual app scripts are in each app's `package.json` (e.g., `pnpm --filter ./apps/backend run dev`).\n- Prisma DB commands: `pnpm run prisma-generate`, `pnpm run prisma-db-push`, `pnpm run prisma-reset`.\n- Docker: `docker compose -f ./docker-compose.dev.yaml up -d`\n\n## Conventions & Patterns\n- Use conventional commits (`feat:`, `fix:`, `chore:`).\n- PRs should include clear descriptions, related issue links, and UI screenshots/GIFs if relevant.\n- Comments are required for complex logic.\n- Shared code lives in `libraries/` (e.g., helpers, React shared libraries, NestJS modules).\n- Environment variables are managed via `.env` and referenced in Docker and scripts.\n- Make sure to keep the `.env.example` file updated with new environment variables.\n\n## Integration Points\n- External APIs: Social media (Instagram, Facebook), Make.com, N8N, Resend, Stripe, etc.\n- SDK (`apps/sdk`) provides programmatic access to Postiz features.\n- Extension (`apps/extension`) is built with Vite, React, TypeScript, and Tailwind CSS.\n\n## Key Files & Directories\n- `apps/` — Main services and applications\n- `libraries/` — Shared code and modules\n- `docker-compose.dev.yaml` — Local development Docker setup\n- `.env` — Environment configuration\n- `jest.config.ts` — Test configuration\n- `pnpm-workspace.yaml` — Workspace package management\n- `README.md` — General project overview\n- `libraries/nestjs-libraries/src/database/prisma/schema.prisma` — Database schema\n\n## Documentation\n- Main docs: https://docs.postiz.com/\n- Developer guide: https://docs.postiz.com/developer-guide\n- Public API: https://docs.postiz.com/public-api\n\n---\n\n# Logs\n\n- Where logs are used, ensure Sentry is imported using `import * as Sentry from \"@sentry/nextjs\"`\n- Enable logging in Sentry using `Sentry.init({ enableLogs: true })`\n- Reference the logger using `const { logger } = Sentry`\n- Sentry offers a `consoleLoggingIntegration` that can be used to log specific console error types automatically without instrumenting the individual logger calls\n\n## Configuration\n\nThe Sentry initialization needs to be updated to enable the logs feature.\n\n### Baseline\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n\n  enableLogs: true,\n});\n```\n\n### Logger Integration\n\n```javascript\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n  integrations: [\n    // send console.log, console.error, and console.warn calls as logs to Sentry\n    Sentry.consoleLoggingIntegration({ levels: [\"log\", \"error\", \"warn\"] }),\n  ],\n});\n```\n\n## Logger Examples\n\n`logger.fmt` is a template literal function that should be used to bring variables into the structured logs.\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nconst { logger } = Sentry;\n\nlogger.trace(\"Starting database connection\", { database: \"users\" });\nlogger.debug(logger.fmt`Cache miss for user: ${userId}`);\nlogger.info(\"Updated profile\", { profileId: 345 });\nlogger.warn(\"Rate limit reached for endpoint\", {\n  endpoint: \"/api/results/\",\n  isEnterprise: false,\n});\nlogger.error(\"Failed to process payment\", {\n  orderId: \"order_123\",\n  amount: 99.99,\n});\nlogger.fatal(\"Database connection pool exhausted\", {\n  database: \"users\",\n  activeConnections: 100,\n});\n```\n\n---\n\nFor questions or unclear conventions, check the main README or ask for clarification in your PR description.\n\n"},"items":[{"name":"nest-cli.json","path":"apps/commands/nest-cli.json","rawUrl":"https://raw.githubusercontent.com/gitroomhq/postiz-app/HEAD/apps/commands/nest-cli.json","title":"Commands Skill","category":"anthropic-skill","format":"json","content":"{\n  \"$schema\": \"https://json.schemastore.org/nest-cli\",\n  \"collection\": \"@nestjs/schematics\",\n  \"monorepo\": false,\n  \"sourceRoot\": \"src\",\n  \"entryFile\": \"../../dist/commands/apps/commands/src/main\",\n  \"language\": \"ts\",\n  \"generateOptions\": {\n    \"spec\": false\n  },\n  \"compilerOptions\": {\n    \"manualRestart\": true,\n    \"tsConfigPath\": \"./tsconfig.build.json\",\n    \"webpack\": false,\n    \"deleteOutDir\": true,\n    \"assets\": [],\n    \"watchAssets\": false,\n    \"plugins\": []\n  }\n}\n","frontmatter":{"$schema":"https://json.schemastore.org/nest-cli","collection":"@nestjs/schematics","monorepo":false,"sourceRoot":"src","entryFile":"../../dist/commands/apps/commands/src/main","language":"ts","generateOptions":{"spec":false},"compilerOptions":{"manualRestart":true,"tsConfigPath":"./tsconfig.build.json","webpack":false,"deleteOutDir":true,"assets":[],"watchAssets":false,"plugins":[]}},"isInternal":false,"tokens":139,"sizeBytes":476},{"name":"package.json","path":"apps/commands/package.json","rawUrl":"https://raw.githubusercontent.com/gitroomhq/postiz-app/HEAD/apps/commands/package.json","title":"postiz-command","category":"anthropic-skill","format":"json","content":"{\n  \"name\": \"postiz-command\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"scripts\": {\n    \"dev\": \"dotenv -e ../../.env -- nest start --watch --entryFile=./apps/command/src/main\",\n    \"build\": \"cross-env NODE_ENV=production nest build\",\n    \"start\": \"node ./dist/apps/command/src/main.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}\n","frontmatter":{"name":"postiz-command","version":"1.0.0","description":"","scripts":{"dev":"dotenv -e ../../.env -- nest start --watch --entryFile=./apps/command/src/main","build":"cross-env NODE_ENV=production nest build","start":"node ./dist/apps/command/src/main.js"},"keywords":[],"author":"","license":"ISC"},"isInternal":false,"tokens":104,"sizeBytes":350},{"name":"tsconfig.build.json","path":"apps/commands/tsconfig.build.json","rawUrl":"https://raw.githubusercontent.com/gitroomhq/postiz-app/HEAD/apps/commands/tsconfig.build.json","title":"Commands Skill","category":"anthropic-skill","format":"json","content":"{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"],\n  \"compilerOptions\": {\n    \"module\": \"CommonJS\",\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"ES2021\",\n    \"sourceMap\": true,\n    \"incremental\": true,\n    \"skipLibCheck\": true,\n    \"strictNullChecks\": false,\n    \"noImplicitAny\": false,\n    \"strictBindCallApply\": false,\n    \"forceConsistentCasingInFileNames\": false,\n    \"noFallthroughCasesInSwitch\": false,\n    \"outDir\": \"./dist\"\n  }\n}\n","frontmatter":{"extends":"./tsconfig.json","exclude":["node_modules","test","dist","**/*spec.ts"],"compilerOptions":{"module":"CommonJS","resolveJsonModule":true,"declaration":true,"removeComments":true,"emitDecoratorMetadata":true,"experimentalDecorators":true,"allowSyntheticDefaultImports":true,"target":"ES2021","sourceMap":true,"incremental":true,"skipLibCheck":true,"strictNullChecks":false,"noImplicitAny":false,"strictBindCallApply":false,"forceConsistentCasingInFileNames":false,"noFallthroughCasesInSwitch":false,"outDir":"./dist"}},"isInternal":false,"tokens":181,"sizeBytes":650},{"name":"tsconfig.json","path":"apps/commands/tsconfig.json","rawUrl":"https://raw.githubusercontent.com/gitroomhq/postiz-app/HEAD/apps/commands/tsconfig.json","title":"Commands Skill","category":"anthropic-skill","format":"json","content":"{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"es2017\",\n    \"sourceMap\": true,\n    \"esModuleInterop\": true\n  }\n}\n","frontmatter":{"extends":"../../tsconfig.base.json","compilerOptions":{"module":"commonjs","declaration":true,"removeComments":true,"allowSyntheticDefaultImports":true,"target":"es2017","sourceMap":true,"esModuleInterop":true}},"isInternal":false,"tokens":74,"sizeBytes":268},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/gitroomhq/postiz-app/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"This project is Postiz, a tool to schedule social media and chat posts to 28+ channels.\nYou can add posts to the calendar, they will be added into a workflow and posted at the right time.\nYou can find things like:\n- Schedule posts\n- Calendar view\n- Analytics\n- Team management\n- Media library\n\nThis project is a monorepo with a root only package.json of dependencies.\nMade with PNPM.\nWe have 3 important folders\n\n- apps/backend - this is where the API code is (NESTJS)\n- apps/orchestrator - this is temporal, it's for background jobs (NESTJS) it contains all the workflows and activities\n- apps/frontend - this is the code of the frontend (Vite ReactJS)\n- /libraries contains a lot of services shared between backend and orchestrator and frontend components.\n\nWe are using only pnpm, don't use any other dependency manager.\nNever install frontend components from npmjs, focus on writing native components.\n\nThe project uses tailwind 3, before writing any component look at:\n- /apps/frontend/src/app/colors.scss\n- /apps/frontend/src/app/global.scss\n- /apps/frontend/tailwind.config.js\n\nAll the --color-custom* are deprecated, don't use them.\n\nAnd check other components in the system before to get the right design.\n\nWhen working on the backend we need to pass the 3 layers:\nDTO >> Controller >> Service >> Repository (no shortcuts)\nIn some cases we will have\nDTO >> Controller >> Manager >> Service >> Repository.\n\nMost of the server logic should be inside of libs/server.\nThe backend repository is mostly used to write controller, and import files from libs.server.\n\nFor the frontend follow this:\n- Many of the UI components lives in /apps/frontend/src/components/ui\n- Routing is in /apps/frontend/src/app\n- Components are in /apps/frontend/src/components\n- always use SWR to fetch stuff, and use \"useFetch\" hook from /libraries/helpers/src/utils/custom.fetch.tsx\n\nWhen using SWR, each one have to be in a separate hook and must comply with react-hooks/rules-of-hooks, never put eslint-disable-next-line on it.\n\nIt means that this is valid:\nconst useCommunity = () => {\n   return useSWR....\n}\n\nThis is not valid:\nconst useCommunity = () => {\n  return {\n    communities: () => useSWR<CommunitiesListResponse>(\"communities\", getCommunities),\n    providers: () => useSWR<ProvidersListResponse>(\"providers\", getProviders),\n  };\n}\n\n- Linting of the project can run only from the root.\n- Use only pnpm.\n- Never use RAW SQL queries, always use Prisma.\n- The system is in production with many users, if you want to change something, you need to be sure that you are not breaking anything for existing users and a migration might be needed\n- Whenever you generate a PR, PR description, or similar, **always** follow the PR Template (.github/PULL_REQUEST_TEMPLATE.md)\n- Every PR description **must** contain a `# QA` section with real, numbered steps a reviewer can follow to verify the change (setup, action, expected result), written so they can be run without asking the author anything. This is not optional and applies to humans and agents alike, including one-line fixes. The section is extracted verbatim and shown on the review board, so:\n  - Use the exact heading `# QA` (`# Testing`, `# Test plan`, `# How to test`, `# How to verify`, `# Verification`, `# Steps to test` and `# Manual testing` are also recognised, but prefer `# QA`). The whole heading must match, so something like `## Testing philosophy` is not picked up.\n  - Never leave the template placeholder in place, and never write `N/A`, `TBD`, `todo`, `none` or a bare empty checkbox as the whole section - those all count as no QA at all and the board will show the PR as missing testing notes.\n  - Steps inside a fenced code block are ignored, so keep them as plain numbered lines. Write each step as a numbered checkbox (`1. [ ] step`) so a reviewer can tick it off while working through it - the numbering is what the board extracts, the checkbox is for the reviewer.\n- Every PR description **must** answer `# What kind of change does this PR introduce?` with actual detail, not just a category. `Bug fix.` / `Feature.` on its own is not acceptable. State the type, the area it touches (backend, frontend, orchestrator, a specific provider or screen), and in one to three sentences what concretely changed and where - the key function, endpoint, file or field - plus what deliberately stayed the same. A reader should understand the change from this section alone, without opening the diff.\n- Avoid as much as possible creating new files with pure logic of algorithms, it's usually wrong\n- When you write code, make sure that what you add looks like something similar somewhere else in the code, don't make weird patterns\n- When you finished running, run another agents that matches the new code with the existing system code, to see that it looks similar and is not a weird pattern.\n- Workflows files can never be changed if they are already in origin/main, because changing a workflow will fail all its activities, instead create a new workflow with the version, and everywhere the workflow being called, change it to the new workflow version.\n- Workflows activities parameters cannot be changed, as it will break the workflow, if we need to change the parameters, if we need to change the parameters, we need to create a new activity with the new parameters, and then create a new workflow that uses the new activity.\n- Code must always be generic, there can't be a way that a specific logic, let's say facebook or instagram, appear in a file that use a generic logic, instead, we need to edit the interface of the provider, add another function, and then generically call it from the generic code, and then implement the specific logic in the provider implementation. we can't have something like if(facebookProvider) {} inside a non facebook provider file.\n- Before adding a field to a shared repository/service `select` or changing a shared method's return shape, grep for all its consumers (frontend, public API, MCP/agent tools, orchestrator, webhooks) and confirm the change is intended for each.\n- Exposing a stored field to a new external surface (public API, MCP, webhooks) is a data-exposure decision — ask first, and check what existing production rows hold for that column before shipping it.\n- Never silently change the meaning or format of a value persisted in an existing DB column; that affects every reader and all historical rows, so ask first. \n- Never return a raw Prisma row from a model that holds credentials (`Integration`, `User` and similar) in a controller response. Repository writes on those models must use a `select` with only the fields the caller needs (like `setTimes` with `select: { id: true }`), or the controller returns nothing. This applies even where nearby code looks different.\n- Be extra careful with code invoked by webhooks of external systems (Stripe, RevenueCat and other payment providers), including everything they call down the stack (e.g. `SubscriptionService.createOrUpdateSubscription`, `modifySubscription`, `deleteSubscription`). That code must not throw exceptions: never add a `throw`, and wrap any call that can fail (DB, provider API) so a failure is caught and logged instead of propagating. A webhook that throws leaves billing state half-applied for a paying customer.\n","isInternal":false,"tokens":1597,"sizeBytes":7305},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/gitroomhq/postiz-app/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"\n# Copilot Coding Agent Instructions for Postiz\n\n## Project Architecture\n- Monorepo managed by NX, with apps in `apps/` and shared code in `libraries/`.\n- Main services: `frontend` (Next.js), `backend` (NestJS), `cron`, `commands`, `extension`, `sdk`, and `workers`.\n- Data layer uses Prisma ORM (`libraries/nestjs-libraries/src/database/prisma/schema.prisma`) with PostgreSQL as the default database.\n- Redis (BullMQ) is used for queues and caching.\n- Email notifications via Resend.\n- Social login integrations (Instagram, Facebook) and Make.com/N8N integrations.\n\n## Developer Workflows\n- Use Node.js 20.17.0 and pnpm 8+.\n- Install dependencies: `pnpm install`\n- Build all apps: `pnpm run build`\n- Run all apps in dev mode: `pnpm run dev`\n- Test: `pnpm test` (Jest, coverage enabled)\n- Individual app scripts are in each app's `package.json` (e.g., `pnpm --filter ./apps/backend run dev`).\n- Prisma DB commands: `pnpm run prisma-generate`, `pnpm run prisma-db-push`, `pnpm run prisma-reset`.\n- Docker: `docker compose -f ./docker-compose.dev.yaml up -d`\n\n## Conventions & Patterns\n- Use conventional commits (`feat:`, `fix:`, `chore:`).\n- PRs should include clear descriptions, related issue links, and UI screenshots/GIFs if relevant.\n- Comments are required for complex logic.\n- Shared code lives in `libraries/` (e.g., helpers, React shared libraries, NestJS modules).\n- Environment variables are managed via `.env` and referenced in Docker and scripts.\n- Make sure to keep the `.env.example` file updated with new environment variables.\n\n## Integration Points\n- External APIs: Social media (Instagram, Facebook), Make.com, N8N, Resend, Stripe, etc.\n- SDK (`apps/sdk`) provides programmatic access to Postiz features.\n- Extension (`apps/extension`) is built with Vite, React, TypeScript, and Tailwind CSS.\n\n## Key Files & Directories\n- `apps/` — Main services and applications\n- `libraries/` — Shared code and modules\n- `docker-compose.dev.yaml` — Local development Docker setup\n- `.env` — Environment configuration\n- `jest.config.ts` — Test configuration\n- `pnpm-workspace.yaml` — Workspace package management\n- `README.md` — General project overview\n- `libraries/nestjs-libraries/src/database/prisma/schema.prisma` — Database schema\n\n## Documentation\n- Main docs: https://docs.postiz.com/\n- Developer guide: https://docs.postiz.com/developer-guide\n- Public API: https://docs.postiz.com/public-api\n\n---\n\n# Logs\n\n- Where logs are used, ensure Sentry is imported using `import * as Sentry from \"@sentry/nextjs\"`\n- Enable logging in Sentry using `Sentry.init({ enableLogs: true })`\n- Reference the logger using `const { logger } = Sentry`\n- Sentry offers a `consoleLoggingIntegration` that can be used to log specific console error types automatically without instrumenting the individual logger calls\n\n## Configuration\n\nThe Sentry initialization needs to be updated to enable the logs feature.\n\n### Baseline\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n\n  enableLogs: true,\n});\n```\n\n### Logger Integration\n\n```javascript\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n  integrations: [\n    // send console.log, console.error, and console.warn calls as logs to Sentry\n    Sentry.consoleLoggingIntegration({ levels: [\"log\", \"error\", \"warn\"] }),\n  ],\n});\n```\n\n## Logger Examples\n\n`logger.fmt` is a template literal function that should be used to bring variables into the structured logs.\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nconst { logger } = Sentry;\n\nlogger.trace(\"Starting database connection\", { database: \"users\" });\nlogger.debug(logger.fmt`Cache miss for user: ${userId}`);\nlogger.info(\"Updated profile\", { profileId: 345 });\nlogger.warn(\"Rate limit reached for endpoint\", {\n  endpoint: \"/api/results/\",\n  isEnterprise: false,\n});\nlogger.error(\"Failed to process payment\", {\n  orderId: \"order_123\",\n  amount: 99.99,\n});\nlogger.fatal(\"Database connection pool exhausted\", {\n  database: \"users\",\n  activeConnections: 100,\n});\n```\n\n---\n\nFor questions or unclear conventions, check the main README or ask for clarification in your PR description.\n\n","isInternal":false,"tokens":1017,"sizeBytes":4170}],"systemPromptSnippet":"<yakaai_skills repo=\"gitroomhq/postiz-app\">\n<!-- File: apps/commands/nest-cli.json (Tokens: ~139 | Category: anthropic-skill) -->\n{\n  \"$schema\": \"https://json.schemastore.org/nest-cli\",\n  \"collection\": \"@nestjs/schematics\",\n  \"monorepo\": false,\n  \"sourceRoot\": \"src\",\n  \"entryFile\": \"../../dist/commands/apps/commands/src/main\",\n  \"language\": \"ts\",\n  \"generateOptions\": {\n    \"spec\": false\n  },\n  \"compilerOptions\": {\n    \"manualRestart\": true,\n    \"tsConfigPath\": \"./tsconfig.build.json\",\n    \"webpack\": false,\n    \"deleteOutDir\": true,\n    \"assets\": [],\n    \"watchAssets\": false,\n    \"plugins\": []\n  }\n}\n\n<!-- File: apps/commands/package.json (Tokens: ~104 | Category: anthropic-skill) -->\n{\n  \"name\": \"postiz-command\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"scripts\": {\n    \"dev\": \"dotenv -e ../../.env -- nest start --watch --entryFile=./apps/command/src/main\",\n    \"build\": \"cross-env NODE_ENV=production nest build\",\n    \"start\": \"node ./dist/apps/command/src/main.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}\n\n<!-- File: apps/commands/tsconfig.build.json (Tokens: ~181 | Category: anthropic-skill) -->\n{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"],\n  \"compilerOptions\": {\n    \"module\": \"CommonJS\",\n    \"resolveJsonModule\": true,\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"ES2021\",\n    \"sourceMap\": true,\n    \"incremental\": true,\n    \"skipLibCheck\": true,\n    \"strictNullChecks\": false,\n    \"noImplicitAny\": false,\n    \"strictBindCallApply\": false,\n    \"forceConsistentCasingInFileNames\": false,\n    \"noFallthroughCasesInSwitch\": false,\n    \"outDir\": \"./dist\"\n  }\n}\n\n<!-- File: apps/commands/tsconfig.json (Tokens: ~74 | Category: anthropic-skill) -->\n{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"declaration\": true,\n    \"removeComments\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"target\": \"es2017\",\n    \"sourceMap\": true,\n    \"esModuleInterop\": true\n  }\n}\n\n<!-- File: CLAUDE.md (Tokens: ~1597 | Category: claude-rule) -->\nThis project is Postiz, a tool to schedule social media and chat posts to 28+ channels.\nYou can add posts to the calendar, they will be added into a workflow and posted at the right time.\nYou can find things like:\n- Schedule posts\n- Calendar view\n- Analytics\n- Team management\n- Media library\n\nThis project is a monorepo with a root only package.json of dependencies.\nMade with PNPM.\nWe have 3 important folders\n\n- apps/backend - this is where the API code is (NESTJS)\n- apps/orchestrator - this is temporal, it's for background jobs (NESTJS) it contains all the workflows and activities\n- apps/frontend - this is the code of the frontend (Vite ReactJS)\n- /libraries contains a lot of services shared between backend and orchestrator and frontend components.\n\nWe are using only pnpm, don't use any other dependency manager.\nNever install frontend components from npmjs, focus on writing native components.\n\nThe project uses tailwind 3, before writing any component look at:\n- /apps/frontend/src/app/colors.scss\n- /apps/frontend/src/app/global.scss\n- /apps/frontend/tailwind.config.js\n\nAll the --color-custom* are deprecated, don't use them.\n\nAnd check other components in the system before to get the right design.\n\nWhen working on the backend we need to pass the 3 layers:\nDTO >> Controller >> Service >> Repository (no shortcuts)\nIn some cases we will have\nDTO >> Controller >> Manager >> Service >> Repository.\n\nMost of the server logic should be inside of libs/server.\nThe backend repository is mostly used to write controller, and import files from libs.server.\n\nFor the frontend follow this:\n- Many of the UI components lives in /apps/frontend/src/components/ui\n- Routing is in /apps/frontend/src/app\n- Components are in /apps/frontend/src/components\n- always use SWR to fetch stuff, and use \"useFetch\" hook from /libraries/helpers/src/utils/custom.fetch.tsx\n\nWhen using SWR, each one have to be in a separate hook and must comply with react-hooks/rules-of-hooks, never put eslint-disable-next-line on it.\n\nIt means that this is valid:\nconst useCommunity = () => {\n   return useSWR....\n}\n\nThis is not valid:\nconst useCommunity = () => {\n  return {\n    communities: () => useSWR<CommunitiesListResponse>(\"communities\", getCommunities),\n    providers: () => useSWR<ProvidersListResponse>(\"providers\", getProviders),\n  };\n}\n\n- Linting of the project can run only from the root.\n- Use only pnpm.\n- Never use RAW SQL queries, always use Prisma.\n- The system is in production with many users, if you want to change something, you need to be sure that you are not breaking anything for existing users and a migration might be needed\n- Whenever you generate a PR, PR description, or similar, **always** follow the PR Template (.github/PULL_REQUEST_TEMPLATE.md)\n- Every PR description **must** contain a `# QA` section with real, numbered steps a reviewer can follow to verify the change (setup, action, expected result), written so they can be run without asking the author anything. This is not optional and applies to humans and agents alike, including one-line fixes. The section is extracted verbatim and shown on the review board, so:\n  - Use the exact heading `# QA` (`# Testing`, `# Test plan`, `# How to test`, `# How to verify`, `# Verification`, `# Steps to test` and `# Manual testing` are also recognised, but prefer `# QA`). The whole heading must match, so something like `## Testing philosophy` is not picked up.\n  - Never leave the template placeholder in place, and never write `N/A`, `TBD`, `todo`, `none` or a bare empty checkbox as the whole section - those all count as no QA at all and the board will show the PR as missing testing notes.\n  - Steps inside a fenced code block are ignored, so keep them as plain numbered lines. Write each step as a numbered checkbox (`1. [ ] step`) so a reviewer can tick it off while working through it - the numbering is what the board extracts, the checkbox is for the reviewer.\n- Every PR description **must** answer `# What kind of change does this PR introduce?` with actual detail, not just a category. `Bug fix.` / `Feature.` on its own is not acceptable. State the type, the area it touches (backend, frontend, orchestrator, a specific provider or screen), and in one to three sentences what concretely changed and where - the key function, endpoint, file or field - plus what deliberately stayed the same. A reader should understand the change from this section alone, without opening the diff.\n- Avoid as much as possible creating new files with pure logic of algorithms, it's usually wrong\n- When you write code, make sure that what you add looks like something similar somewhere else in the code, don't make weird patterns\n- When you finished running, run another agents that matches the new code with the existing system code, to see that it looks similar and is not a weird pattern.\n- Workflows files can never be changed if they are already in origin/main, because changing a workflow will fail all its activities, instead create a new workflow with the version, and everywhere the workflow being called, change it to the new workflow version.\n- Workflows activities parameters cannot be changed, as it will break the workflow, if we need to change the parameters, if we need to change the parameters, we need to create a new activity with the new parameters, and then create a new workflow that uses the new activity.\n- Code must always be generic, there can't be a way that a specific logic, let's say facebook or instagram, appear in a file that use a generic logic, instead, we need to edit the interface of the provider, add another function, and then generically call it from the generic code, and then implement the specific logic in the provider implementation. we can't have something like if(facebookProvider) {} inside a non facebook provider file.\n- Before adding a field to a shared repository/service `select` or changing a shared method's return shape, grep for all its consumers (frontend, public API, MCP/agent tools, orchestrator, webhooks) and confirm the change is intended for each.\n- Exposing a stored field to a new external surface (public API, MCP, webhooks) is a data-exposure decision — ask first, and check what existing production rows hold for that column before shipping it.\n- Never silently change the meaning or format of a value persisted in an existing DB column; that affects every reader and all historical rows, so ask first. \n- Never return a raw Prisma row from a model that holds credentials (`Integration`, `User` and similar) in a controller response. Repository writes on those models must use a `select` with only the fields the caller needs (like `setTimes` with `select: { id: true }`), or the controller returns nothing. This applies even where nearby code looks different.\n- Be extra careful with code invoked by webhooks of external systems (Stripe, RevenueCat and other payment providers), including everything they call down the stack (e.g. `SubscriptionService.createOrUpdateSubscription`, `modifySubscription`, `deleteSubscription`). That code must not throw exceptions: never add a `throw`, and wrap any call that can fail (DB, provider API) so a failure is caught and logged instead of propagating. A webhook that throws leaves billing state half-applied for a paying customer.\n\n<!-- File: .github/copilot-instructions.md (Tokens: ~1017 | Category: copilot-instructions) -->\n# Copilot Coding Agent Instructions for Postiz\n\n## Project Architecture\n- Monorepo managed by NX, with apps in `apps/` and shared code in `libraries/`.\n- Main services: `frontend` (Next.js), `backend` (NestJS), `cron`, `commands`, `extension`, `sdk`, and `workers`.\n- Data layer uses Prisma ORM (`libraries/nestjs-libraries/src/database/prisma/schema.prisma`) with PostgreSQL as the default database.\n- Redis (BullMQ) is used for queues and caching.\n- Email notifications via Resend.\n- Social login integrations (Instagram, Facebook) and Make.com/N8N integrations.\n\n## Developer Workflows\n- Use Node.js 20.17.0 and pnpm 8+.\n- Install dependencies: `pnpm install`\n- Build all apps: `pnpm run build`\n- Run all apps in dev mode: `pnpm run dev`\n- Test: `pnpm test` (Jest, coverage enabled)\n- Individual app scripts are in each app's `package.json` (e.g., `pnpm --filter ./apps/backend run dev`).\n- Prisma DB commands: `pnpm run prisma-generate`, `pnpm run prisma-db-push`, `pnpm run prisma-reset`.\n- Docker: `docker compose -f ./docker-compose.dev.yaml up -d`\n\n## Conventions & Patterns\n- Use conventional commits (`feat:`, `fix:`, `chore:`).\n- PRs should include clear descriptions, related issue links, and UI screenshots/GIFs if relevant.\n- Comments are required for complex logic.\n- Shared code lives in `libraries/` (e.g., helpers, React shared libraries, NestJS modules).\n- Environment variables are managed via `.env` and referenced in Docker and scripts.\n- Make sure to keep the `.env.example` file updated with new environment variables.\n\n## Integration Points\n- External APIs: Social media (Instagram, Facebook), Make.com, N8N, Resend, Stripe, etc.\n- SDK (`apps/sdk`) provides programmatic access to Postiz features.\n- Extension (`apps/extension`) is built with Vite, React, TypeScript, and Tailwind CSS.\n\n## Key Files & Directories\n- `apps/` — Main services and applications\n- `libraries/` — Shared code and modules\n- `docker-compose.dev.yaml` — Local development Docker setup\n- `.env` — Environment configuration\n- `jest.config.ts` — Test configuration\n- `pnpm-workspace.yaml` — Workspace package management\n- `README.md` — General project overview\n- `libraries/nestjs-libraries/src/database/prisma/schema.prisma` — Database schema\n\n## Documentation\n- Main docs: https://docs.postiz.com/\n- Developer guide: https://docs.postiz.com/developer-guide\n- Public API: https://docs.postiz.com/public-api\n\n---\n\n# Logs\n\n- Where logs are used, ensure Sentry is imported using `import * as Sentry from \"@sentry/nextjs\"`\n- Enable logging in Sentry using `Sentry.init({ enableLogs: true })`\n- Reference the logger using `const { logger } = Sentry`\n- Sentry offers a `consoleLoggingIntegration` that can be used to log specific console error types automatically without instrumenting the individual logger calls\n\n## Configuration\n\nThe Sentry initialization needs to be updated to enable the logs feature.\n\n### Baseline\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n\n  enableLogs: true,\n});\n```\n\n### Logger Integration\n\n```javascript\nSentry.init({\n  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,\n  integrations: [\n    // send console.log, console.error, and console.warn calls as logs to Sentry\n    Sentry.consoleLoggingIntegration({ levels: [\"log\", \"error\", \"warn\"] }),\n  ],\n});\n```\n\n## Logger Examples\n\n`logger.fmt` is a template literal function that should be used to bring variables into the structured logs.\n\n```javascript\nimport * as Sentry from \"@sentry/nextjs\";\n\nconst { logger } = Sentry;\n\nlogger.trace(\"Starting database connection\", { database: \"users\" });\nlogger.debug(logger.fmt`Cache miss for user: ${userId}`);\nlogger.info(\"Updated profile\", { profileId: 345 });\nlogger.warn(\"Rate limit reached for endpoint\", {\n  endpoint: \"/api/results/\",\n  isEnterprise: false,\n});\nlogger.error(\"Failed to process payment\", {\n  orderId: \"order_123\",\n  amount: 99.99,\n});\nlogger.fatal(\"Database connection pool exhausted\", {\n  database: \"users\",\n  activeConnections: 100,\n});\n```\n\n---\n\nFor questions or unclear conventions, check the main README or ask for clarification in your PR description.\n</yakaai_skills>"}