diff --git a/.env.vercel.production b/.env.vercel.production deleted file mode 100644 index 4f6a272..0000000 --- a/.env.vercel.production +++ /dev/null @@ -1,25 +0,0 @@ -# Created by Vercel CLI -NX_DAEMON="false" -TURBO_CACHE="remote:rw" -TURBO_DOWNLOAD_LOCAL_ENABLED="true" -TURBO_REMOTE_ONLY="true" -TURBO_RUN_SUMMARY="true" -VERCEL="1" -VERCEL_ENV="production" -VERCEL_GIT_COMMIT_AUTHOR_LOGIN="" -VERCEL_GIT_COMMIT_AUTHOR_NAME="" -VERCEL_GIT_COMMIT_MESSAGE="" -VERCEL_GIT_COMMIT_REF="" -VERCEL_GIT_COMMIT_SHA="" -VERCEL_GIT_PREVIOUS_SHA="" -VERCEL_GIT_PROVIDER="" -VERCEL_GIT_PULL_REQUEST_ID="" -VERCEL_GIT_REPO_ID="" -VERCEL_GIT_REPO_OWNER="" -VERCEL_GIT_REPO_SLUG="" -VERCEL_OIDC_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im1yay00MzAyZWMxYjY3MGY0OGE5OGFkNjFkYWRlNGEyM2JlNyJ9.eyJpc3MiOiJodHRwczovL29pZGMudmVyY2VsLmNvbS95dXp1cnV1MjlzLXByb2plY3RzIiwic3ViIjoib3duZXI6eXV6dXJ1dTI5cy1wcm9qZWN0czpwcm9qZWN0OmFwcGx5Z3VhcmQtcGg6ZW52aXJvbm1lbnQ6ZGV2ZWxvcG1lbnQiLCJzY29wZSI6Im93bmVyOnl1enVydXUyOXMtcHJvamVjdHM6cHJvamVjdDphcHBseWd1YXJkLXBoOmVudmlyb25tZW50OmRldmVsb3BtZW50IiwiYXVkIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3l1enVydXUyOXMtcHJvamVjdHMiLCJvd25lciI6Inl1enVydXUyOXMtcHJvamVjdHMiLCJvd25lcl9pZCI6InRlYW1fUkVENnZhZkdlTE1qU3hRUUtBYTcyQ3JqIiwicHJvamVjdCI6ImFwcGx5Z3VhcmQtcGgiLCJwcm9qZWN0X2lkIjoicHJqX3B5TENUQWZuSE41ZTY2eEpCaHJxREltekV2SWIiLCJlbnZpcm9ubWVudCI6ImRldmVsb3BtZW50IiwicGxhbiI6ImhvYmJ5IiwidXNlcl9pZCI6InFTQ0hOelhmalNlSmhkeEY3aVpsS3RrWSIsImNsaWVudF9pZCI6ImNsX0hZeU9QQk50Rk1mSGhhVW45TDRRUGZUWno2VFA0N2JwIiwibmJmIjoxNzg0Mzk5MDE3LCJpYXQiOjE3ODQzOTkwMTcsImV4cCI6MTc4NDQ0MjIxN30.lyj34RJpWcuvmh1KbiA1CWp5ZJ-8sHPG7rxaKeRIy9zgiUzLrnVO27-7RkFbn-dekQyVkdxiRaBVisFMQIYCCvkqChYDg125xhAcW4OqfH4wuaXE5rGwrUX10flTa4NyGI_CO3X6Rj8DR5eEkPUA8-tW2ArXWz9d_T_n2xuqCduCRlSiQDMFz8-w7ju0vae2Ng95pMo3R3jmGdplhN056ovOLSLEAwNScddKDkljjxi7_gNZhytYg76uBfzOTZEhU5ZuC9PZl2drfdNLMo9jZqQNyA_I0E7HcJaxU9E3NTaovWCXeJRBhQ-BgxdTbUT2YNjCDvX5kmh_Xrmez8MzhQ" -VERCEL_TARGET_ENV="production" -VERCEL_URL="" -VITE_PAYPAL_CLIENT_ID="" -VITE_SUPABASE_ANON_KEY="" -VITE_SUPABASE_URL="" diff --git a/.env.vercel.production.2 b/.env.vercel.production.2 deleted file mode 100644 index 4b65c3e..0000000 --- a/.env.vercel.production.2 +++ /dev/null @@ -1,25 +0,0 @@ -# Created by Vercel CLI -NX_DAEMON="false" -TURBO_CACHE="remote:rw" -TURBO_DOWNLOAD_LOCAL_ENABLED="true" -TURBO_REMOTE_ONLY="true" -TURBO_RUN_SUMMARY="true" -VERCEL="1" -VERCEL_ENV="production" -VERCEL_GIT_COMMIT_AUTHOR_LOGIN="" -VERCEL_GIT_COMMIT_AUTHOR_NAME="" -VERCEL_GIT_COMMIT_MESSAGE="" -VERCEL_GIT_COMMIT_REF="" -VERCEL_GIT_COMMIT_SHA="" -VERCEL_GIT_PREVIOUS_SHA="" -VERCEL_GIT_PROVIDER="" -VERCEL_GIT_PULL_REQUEST_ID="" -VERCEL_GIT_REPO_ID="" -VERCEL_GIT_REPO_OWNER="" -VERCEL_GIT_REPO_SLUG="" -VERCEL_OIDC_TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im1yay00MzAyZWMxYjY3MGY0OGE5OGFkNjFkYWRlNGEyM2JlNyJ9.eyJpc3MiOiJodHRwczovL29pZGMudmVyY2VsLmNvbS95dXp1cnV1MjlzLXByb2plY3RzIiwic3ViIjoib3duZXI6eXV6dXJ1dTI5cy1wcm9qZWN0czpwcm9qZWN0OmFwcGx5Z3VhcmQtcGg6ZW52aXJvbm1lbnQ6ZGV2ZWxvcG1lbnQiLCJzY29wZSI6Im93bmVyOnl1enVydXUyOXMtcHJvamVjdHM6cHJvamVjdDphcHBseWd1YXJkLXBoOmVudmlyb25tZW50OmRldmVsb3BtZW50IiwiYXVkIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3l1enVydXUyOXMtcHJvamVjdHMiLCJvd25lciI6Inl1enVydXUyOXMtcHJvamVjdHMiLCJvd25lcl9pZCI6InRlYW1fUkVENnZhZkdlTE1qU3hRUUtBYTcyQ3JqIiwicHJvamVjdCI6ImFwcGx5Z3VhcmQtcGgiLCJwcm9qZWN0X2lkIjoicHJqX3B5TENUQWZuSE41ZTY2eEpCaHJxREltekV2SWIiLCJlbnZpcm9ubWVudCI6ImRldmVsb3BtZW50IiwicGxhbiI6ImhvYmJ5IiwidXNlcl9pZCI6InFTQ0hOelhmalNlSmhkeEY3aVpsS3RrWSIsImNsaWVudF9pZCI6ImNsX0hZeU9QQk50Rk1mSGhhVW45TDRRUGZUWno2VFA0N2JwIiwibmJmIjoxNzg0Mzk5NzAxLCJpYXQiOjE3ODQzOTk3MDEsImV4cCI6MTc4NDQ0MjkwMX0.PVl4AG8zzJNuAPawahVsn_9nis3fbsv6BVOkMvMjMaWJhVEIdKxyyyfVObho2WSnh5LUa33Lqdi7el-cUN5mbaLhjaVXvWJOJF58p2jxQQ_U5osBECCqYQhtYFFY65-SpcAX-CWGZWySOnAuNDelT0RTOGCv2fEV7Ja0Rz56wLD5UaqWy-rcQ0D4XnexZrhm5NKSOUM48NKnjC6vunik2cGs-7pcPU4-PdjdBoXRj9ErLSe-1MkZEMu91ADlqlCihGRnjgOBrt9jlFgp-IQ82BPEY2F-a-YHQEVDeaMpHN44ePsdtG2S5cIdo3zkIrKt9e48f3nweEA-kXQW0dLGXA" -VERCEL_TARGET_ENV="production" -VERCEL_URL="" -VITE_PAYPAL_CLIENT_ID="" -VITE_SUPABASE_ANON_KEY="" -VITE_SUPABASE_URL="" diff --git a/.github/workflows/supabase.yml b/.github/workflows/supabase.yml index daefe75..a12589c 100644 --- a/.github/workflows/supabase.yml +++ b/.github/workflows/supabase.yml @@ -1,4 +1,4 @@ -name: Deploy Edge Functions +name: Deploy Edge Functions & Migrations on: push: @@ -6,17 +6,60 @@ on: - main paths: - 'supabase/functions/**' + - 'supabase/migrations/**' + - 'supabase/tests/**' + - 'supabase/config.toml' + - '.github/workflows/supabase.yml' + pull_request: + branches: + - main + paths: + - 'supabase/functions/**' + - 'supabase/migrations/**' + - 'supabase/tests/**' + - 'supabase/config.toml' + - '.github/workflows/supabase.yml' jobs: + validate: + name: Test & Build Validation + runs-on: ubuntu-latest + concurrency: + group: pr-validation-${{ github.ref }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Run unit tests + run: npm test + + - name: Run build + run: npm run build + deploy: + name: Migrate Database & Deploy Edge Functions + needs: validate + if: github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest + concurrency: + group: production_deployment_pipeline + cancel-in-progress: false env: SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} PROJECT_ID: ${{ secrets.SUPABASE_PROJECT_ID }} + SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: @@ -26,18 +69,27 @@ jobs: - name: Install dependencies run: npm ci - - name: Run unit tests - run: npm test - - uses: supabase/setup-cli@v1 with: version: latest - - name: Deploy create-checkout - run: supabase functions deploy create-checkout --project-ref $PROJECT_ID + - name: Link Supabase Project + run: supabase link --project-ref $PROJECT_ID --password $SUPABASE_DB_PASSWORD + + - name: Apply Database Migrations + run: supabase db push --password $SUPABASE_DB_PASSWORD + + - name: Deploy ai-proxy + run: supabase functions deploy ai-proxy --project-ref $PROJECT_ID + + - name: Deploy create-paypal-order + run: supabase functions deploy create-paypal-order --project-ref $PROJECT_ID + + - name: Deploy capture-paypal-order + run: supabase functions deploy capture-paypal-order --project-ref $PROJECT_ID - - name: Deploy paymongo-webhook - run: supabase functions deploy paymongo-webhook --project-ref $PROJECT_ID --no-verify-jwt + - name: Deploy paypal-webhook + run: supabase functions deploy paypal-webhook --project-ref $PROJECT_ID --no-verify-jwt - - name: Deploy cancel-subscription - run: supabase functions deploy cancel-subscription --project-ref $PROJECT_ID + - name: Deploy download-message-pack + run: supabase functions deploy download-message-pack --project-ref $PROJECT_ID diff --git a/.gitignore b/.gitignore index 0f44777..9af4958 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,10 @@ supabase-go.exe supabase.exe supabase_cli.zip supabase/.temp/ + +# pre-reformat backup +.env +.env.local +.env.*.local + +.vercel diff --git a/.preview-hero.png b/.preview-hero.png new file mode 100644 index 0000000..c03a51f Binary files /dev/null and b/.preview-hero.png differ diff --git a/.preview-hero2.png b/.preview-hero2.png new file mode 100644 index 0000000..572cf29 Binary files /dev/null and b/.preview-hero2.png differ diff --git a/.preview-narrative.png b/.preview-narrative.png new file mode 100644 index 0000000..8612594 Binary files /dev/null and b/.preview-narrative.png differ diff --git a/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/canvas.json b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/canvas.json new file mode 100644 index 0000000..5033c40 --- /dev/null +++ b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/canvas.json @@ -0,0 +1,120 @@ +{ + "schemaVersion": 1, + "summary": { + "evidenceMode": "session-limited", + "evidenceBoundary": { + "manifest": { + "schemaVersion": 2, + "sourceFingerprint": "c230073388d2d558", + "adapterVersion": "qoder-task-loop-source-v2", + "platform": "qoder", + "selection": { + "strategy": "all-eligible", + "eligibleCount": 0, + "analyzedCount": 0, + "confidence": "Low" + } + }, + "deliveryEvidenceLevels": [], + "sourceGaps": [] + }, + "semanticFacets": { + "schemaVersion": 1, + "status": "supplementary", + "entries": [ + { + "id": "session-insight:source-coverage", + "kind": "redacted-summary", + "episodeRef": null, + "status": "candidate", + "labels": [ + "source-coverage", + "Low" + ], + "summary": "Analyzed 0 of 0 sessions; 0/5 enabled source roots exist. Use this as the current workspace evidence boundary for final insight cards.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + }, + { + "id": "session-insight:validation-behavior", + "kind": "redacted-summary", + "episodeRef": null, + "status": "candidate", + "labels": [ + "validation-behavior", + "Low" + ], + "summary": "No validation command category was observed in the analyzed session sample. Inspect more sessions or add explicit validation guidance before claiming validation-after-edit behavior.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + }, + { + "id": "session-insight:post-edit-validation", + "kind": "rework-correction", + "episodeRef": null, + "status": "candidate", + "labels": [ + "post-edit-validation", + "Low" + ], + "summary": "No edit event was observed in the analyzed sample. Inspect more sessions before making claims about edit or validation habits.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + }, + { + "id": "session-insight:execution-friction", + "kind": "friction-taxonomy", + "episodeRef": null, + "status": "candidate", + "labels": [ + "execution-friction", + "Low" + ], + "summary": "No strong execution friction signal in the analyzed sample. Keep friction claims narrow unless additional failed commands, rejected actions, or warnings are inspected.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + } + ] + }, + "learningCapture": { + "schemaVersion": 1, + "state": "N/A", + "summary": "N/A — requires two comparable observation windows and an intervention comparison.", + "interventions": [] + } + }, + "dimensions": [ + { + "id": "task-understanding" + }, + { + "id": "controlled-execution" + }, + { + "id": "change-validation" + }, + { + "id": "reliable-delivery" + }, + { + "id": "learning-capture" + } + ], + "findings": [ + { + "id": "agent-instructions-missing" + }, + { + "id": "no-frontend-ci-validation" + }, + { + "id": "missing-runtime-pin" + }, + { + "id": "no-integration-e2e-tests" + }, + { + "id": "no-recovery-plan-for-payment-state" + } + ] +} diff --git a/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/findings.json b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/findings.json new file mode 100644 index 0000000..1d820ec --- /dev/null +++ b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/findings.json @@ -0,0 +1,199 @@ +{ + "summary": { + "projectName": "ApplyGuard PH", + "locale": "en", + "modelId": "agent-work-loop-v4", + "reportContractVersion": 24, + "overview": "ApplyGuard PH has a clear public README, 10 unit-test files for pure-logic modules, and a Supabase CI pipeline, but lacks agent-oriented guidance, environment pinning, and delivery-side validation, making agent work heavily reliant on implicit knowledge and unchecked changes.", + "aiAgentPractice": { + "inspectedSurfaces": [ + "Rules", + "Skills", + "Hooks" + ], + "coverageRows": [ + { + "surface": "Rules", + "scopes": [ + "Project" + ], + "count": 0, + "paths": [] + }, + { + "surface": "Skills", + "scopes": [ + "Project" + ], + "count": 0, + "paths": [] + }, + { + "surface": "Hooks", + "scopes": [ + "Project", + "Global" + ], + "count": 0, + "paths": [] + } + ] + }, + "suggestions": [ + { + "id": "scaffold-agent-entrypoint", + "kind": "loop-candidate", + "title": "Create an agent entrypoint (AGENTS.md)", + "reason": "The project has no agent-oriented guidance; adding an entrypoint would let agents find the right context, risk areas, and test routes without manual discovery or human handoffs.", + "confidence": "Medium", + "owner": "Project maintainer", + "nextStep": "Write a short AGENTS.md (80-120 lines) that maps source directories, identifies high-risk areas (payments, data deletion, auth), and lists validation commands by scope.", + "validation": "Agent can open AGENTS.md and find the correct test command, deployment path, and payment-risk warning." + }, + { + "id": "add-test-ci-gate", + "kind": "loop-candidate", + "title": "Add Vitest run to CI workflow", + "reason": "The Supabase CI deploys edge functions but never runs the frontend test suite; a test failure on main has no automated safety net.", + "confidence": "High", + "owner": "Project maintainer", + "nextStep": "Add a `npm test` step to .github/workflows/supabase.yml before deployment, or create a separate frontend CI workflow.", + "validation": "Pushing a failing test to a PR branch produces a non-zero exit and visible CI failure." + }, + { + "id": "pin-node-version", + "kind": "try-existing", + "title": "Add .nvmrc for reproducible runtime", + "reason": "Netlify uses NODE_VERSION=20 in netlify.toml, but no project-level pin exists for local or CI environments, creating implicit version assumptions.", + "confidence": "High", + "owner": "Project maintainer", + "nextStep": "Create .nvmrc with the Node version that matches netlify.toml (20) and verify local dev still works.", + "validation": "`node --version` matches the pinned version after `nvm use` (or the agent reads .nvmrc before install commands)." + } + ], + "assignmentSummaries": [], + "dimensions": [ + { + "id": "task-understanding", + "label": "Task Understanding", + "score": 45, + "summary": "Human-oriented README covers architecture well, but no agent entrypoint (AGENTS.md, CLAUDE.md) exists; risk areas and task routes are undocumented for agent readers.", + "findingRefs": [ + "agent-instructions-missing" + ] + }, + { + "id": "controlled-execution", + "label": "Controlled Execution", + "score": 60, + "summary": "Package.json scripts are clear and lockfile is present, but no .nvmrc, no devcontainer, and no state-reset or doctor commands; environment assumptions remain partly implicit.", + "findingRefs": [ + "missing-runtime-pin" + ] + }, + { + "id": "change-validation", + "label": "Change Validation", + "score": 52, + "summary": "10 well-structured unit-test files cover core logic; however, no fast/slow test separation, no integration or E2E tests, and CI does not run the test suite before deployment.", + "findingRefs": [ + "no-frontend-ci-validation", + "no-integration-e2e-tests" + ] + }, + { + "id": "reliable-delivery", + "label": "Reliable Delivery", + "score": 48, + "summary": "Supabase Edge Function CI enforces deployment, but frontend has no CI gate; payment verification has server-side validation but no observable rollback plan or approval path for agent-produced changes.", + "findingRefs": [ + "no-recovery-plan-for-payment-state" + ] + }, + { + "id": "learning-capture", + "label": "Learning Capture", + "score": 35, + "summary": "No .qoder directory, project skills, hooks, or memory configuration; the reviewed window is clean of candidates but also lacks any mechanism for lifecycle detection or reuse.", + "findingRefs": [] + } + ] + }, + "findings": [ + { + "id": "agent-instructions-missing", + "title": "No agent entrypoint or scoped guidance for task routing", + "severity": "High", + "reason": "The project has no AGENTS.md, CLAUDE.md, or equivalent agent guidance. The README (148 lines) serves a human audience. An agent must infer project boundaries, risk areas (payment verification, data deletion, AI proxy keys), and validation routes by scanning the full repository, which increases the chance of incorrect scope, missing test requirements, or unsafe operations.", + "expectedOutput": [ + "Add AGENTS.md with directory map, risk areas, validations-per-scope, and deployment notes.", + "Agent can find the correct test command, deployment path, and payment-risk warning from the entrypoint." + ], + "expectedArtifact": "AGENTS.md", + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a project-level AGENTS.md that maps src/ and supabase/ directories, flags high-risk areas (payment verification, data deletion, auth), and lists validation commands by scope.", + "dimensionRefs": [ + "task-understanding" + ] + }, + { + "id": "no-frontend-ci-validation", + "title": "Frontend unit tests never run in CI", + "severity": "High", + "reason": "The only CI workflow (supabase.yml) deploys Supabase Edge Functions but does not run `npm test` for the 10 frontend unit-test files. A regression in core scoring, red-flag, or entitlement logic can reach main without automated detection.", + "expectedOutput": [ + "Add test step (npm test) to CI workflow.", + "Pushing a failing test produces a non-zero exit and visible CI failure." + ], + "expectedArtifact": ".github/workflows/supabase.yml", + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a `npm test` step before the deployment steps in .github/workflows/supabase.yml so that unit tests run on every push to the supabase/functions path.", + "dimensionRefs": [ + "change-validation" + ] + }, + { + "id": "missing-runtime-pin", + "title": "Node.js runtime version not pinned at project root", + "severity": "Medium", + "reason": "Netlify config pins NODE_VERSION=20 in netlify.toml, but there is no .nvmrc or .tool-versions at the project root. Package.json engines field is absent. This creates implicit, unverifiable runtime assumptions for local dev and CI environments.", + "expectedOutput": [ + "Create .nvmrc with Node engine version matching netlify.toml (20.x).", + "Explicit runtime constraint for agent setup and CI." + ], + "expectedArtifact": ".nvmrc", + "aiFixPrompt": "/better-loop fix this issue\n\nCreate a .nvmrc file matching the Node version from netlify.toml (NODE_VERSION = \"20\").", + "dimensionRefs": [ + "controlled-execution" + ] + }, + { + "id": "no-integration-e2e-tests", + "title": "No integration or E2E test coverage for critical user flows", + "severity": "Medium", + "reason": "All 10 test files are unit tests targeting pure functions. The scan → score → verdict → save flow, cloud sync, payment flows, and SPA routing have no integration or E2E coverage. An agent changing React components, routing, or storage has no automated way to verify the end-to-end behavior still works.", + "expectedOutput": [ + "Add integration test covering the end-to-end scan flow.", + "Agent can run a flow-level test to validate behavior after changes." + ], + "expectedArtifact": "Integration test file(s)", + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a Playwright or Vitest integration test for the scan→score→verdict→save flow. Place it at src/lib/flow.test.js and verify it exercises the core pipeline.", + "dimensionRefs": [ + "change-validation" + ] + }, + { + "id": "no-recovery-plan-for-payment-state", + "title": "Payment and data-deletion recovery has no documented owner route", + "severity": "Medium", + "reason": "The project handles live PayPal payments and user data in Supabase. The README describes server-side verification and webhook fulfillment, but there is no documented rollback, recovery, or escalation plan for agent-facing payment operations, failed captures, or accidental data deletion. An agent has no owned route to follow on recovery.", + "expectedOutput": [ + "Add recovery/rollback documentation covering payment capture failure, webhook reconciliation, and data restoration.", + "Agent can find the owned recovery route after a payment failure." + ], + "expectedArtifact": "Recovery documentation", + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a recovery section either in a new AGENTS.md or docs/ directory that covers: (1) what to do on PayPal capture failure, (2) how to reconcile webhook delivery gaps, (3) how to restore user data from Supabase. Keep it actionable for an agent operator.", + "dimensionRefs": [ + "reliable-delivery" + ] + } + ] +} diff --git a/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/report.canvas.tsx b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/report.canvas.tsx new file mode 100644 index 0000000..b2d1517 --- /dev/null +++ b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/011632-applyguard-ph/report.canvas.tsx @@ -0,0 +1,1786 @@ +import { + AreaChart, + Button, + Callout, + Card, + CardBody, + CardHeader, + CollapsibleSection, + Dialog, + Divider, + Fluency, + Grid, + H1, + H2, + MetricsGrid, + Row, + RiskHeatmap, + SendToChatButton, + Stack, + Table, + Tag, + Text, +} from "qoder/canvas"; +import hostReportData from "./findings.json"; +import canvasData from "./canvas.json"; + +function mergeCanvasRows(hostRows, canvasRows) { + const detailById = new Map( + (Array.isArray(canvasRows) ? canvasRows : []) + .filter((row) => row && typeof row === "object" && typeof row.id === "string") + .map((row) => [row.id, row]), + ); + return (Array.isArray(hostRows) ? hostRows : []).map((row) => ({ ...detailById.get(row?.id), ...row })); +} + +function mergeCanvasObjects(host, detail) { + if (!host || typeof host !== "object" || Array.isArray(host)) return detail; + if (!detail || typeof detail !== "object" || Array.isArray(detail)) return host; + const merged = { ...host }; + for (const [key, value] of Object.entries(detail)) { + merged[key] = value && typeof value === "object" && !Array.isArray(value) + ? mergeCanvasObjects(host[key], value) + : value; + } + return merged; +} + +function mergeCanvasReport(host, detail) { + const summary = host?.summary ?? {}; + if (!detail || typeof detail !== "object" || Array.isArray(detail)) return host; + return { + summary: { + ...(detail?.summary ?? {}), + ...summary, + atAGlance: mergeCanvasObjects(detail?.summary?.atAGlance, summary.atAGlance), + dimensions: mergeCanvasRows(summary.dimensions, detail?.dimensions), + }, + findings: mergeCanvasRows(host?.findings, detail?.findings), + }; +} + +const report = mergeCanvasReport(hostReportData, canvasData); + +const pageStyle = { maxWidth: 960, margin: "0 auto", padding: 16, boxSizing: "border-box" }; +const taskLoopPageStyle = { ...pageStyle, padding: 20 }; +const taskLoopReaderCopyStyle = { maxWidth: 940 }; + +const DIMENSION_SUMMARY_EXAMPLE = "Example: project guidance makes the main workflow clear, but ownership for cross-cutting changes is not documented."; + +function list(value) { + return Array.isArray(value) ? value : []; +} + +function clampScore(value) { + const score = Number(value); + if (!Number.isFinite(score)) return 0; + return Math.max(0, Math.min(100, score)); +} + +function projectName() { + return report.summary?.projectName ?? "Qoder Harness Report"; +} + +function textValue(value) { + return typeof value === "string" ? value.trim() : ""; +} + +function openingStrengths() { + const explicit = list(report.summary?.strengths).map(textValue).filter(Boolean); + return explicit.length ? explicit.slice(0, 3) : ["Reviewed project signals are organized into dimensions and issue findings."]; +} + +function averageScore(dimensions) { + if (dimensions.length === 0) return 0; + return Math.round(dimensions.reduce((sum, row) => sum + clampScore(row.score), 0) / dimensions.length); +} + +function scoreTone(score) { + if (score >= 70) return "success"; + if (score >= 40) return "warning"; + return "danger"; +} + +function stageStatus(score) { + if (score >= 70) return "high"; + if (score >= 40) return "medium"; + if (score > 0) return "low"; + return "blocked"; +} + +function fluencyReason(row) { + return textValue(row?.summary) || taskLoopCopy( + "No reviewed score explanation is available for this dimension.", + "这个维度暂时没有经过复核的评分说明。", + ); +} + +function splitFluencyTooltipReason(value) { + let remaining = textValue(value).replace(/\s+/g, " "); + const chunks = []; + const limits = /[\u3400-\u9fff]/.test(remaining) ? [20, 20, 20, 20] : [34, 30, 30, 30]; + for (const limit of limits) { + if (!remaining) break; + if (remaining.length <= limit) { + chunks.push(remaining); + remaining = ""; + break; + } + let cut = remaining.lastIndexOf(" ", limit); + if (cut < Math.floor(limit * 0.55)) cut = limit; + chunks.push(remaining.slice(0, cut).trim()); + remaining = remaining.slice(cut).trim(); + } + if (remaining && chunks.length) { + chunks[chunks.length - 1] = `${chunks[chunks.length - 1].slice(0, 29)}…`; + } + return chunks; +} + +function dimensionFluencyStages(dimensions) { + return dimensions.map((row) => { + const score = clampScore(row.score); + const usesGenericBand = row.id !== "learning-capture"; + return { + id: row.id, + name: taskLoopDimensionLabel(row.id), + score, + ...(usesGenericBand ? { status: stageStatus(score), blocker: score <= 20 } : {}), + }; + }); +} + +function dimensionFluencyTooltip(row) { + const [title, ...rows] = splitFluencyTooltipReason(fluencyReason(row)); + return { + title, + rows: rows.map((value) => ({ value })), + }; +} + +function severityTone(value) { + if (value === "Critical" || value === "High") return "danger"; + if (value === "Medium") return "warning"; + if (value === "Low") return "success"; + return "neutral"; +} + +function severityRank(value) { + if (value === "Critical") return 0; + if (value === "High") return 1; + if (value === "Medium") return 2; + if (value === "Low") return 3; + return 4; +} + +function dimensionLabel(id, dimensions) { + const match = dimensions.find((row) => row.id === id); + return match?.label ?? id.replace(/-/g, " "); +} + +function aiAgentPractice() { + return report.summary?.aiAgentPractice ?? {}; +} + +function practiceRows() { + const rows = aiAgentPractice().coverageRows; + return Array.isArray(rows) ? rows : []; +} + +function inspectedSurfaces() { + const surfaces = aiAgentPractice().inspectedSurfaces; + return Array.isArray(surfaces) ? surfaces : []; +} + +function visiblePracticePaths(value) { + return list(value).map(textValue).filter((candidate) => candidate + && !candidate.includes("SharedClientCache/projects/") + && !candidate.startsWith("/") + && !/^[A-Za-z]:[\\/]/.test(candidate) + && !candidate.split(/[\\/]/).includes("..")); +} + +function practiceDescription(surface) { + const descriptions = { + Rules: ["Standing project guidance and task-routing instructions.", "项目常驻指引与任务路由说明。"], + Skills: ["Reusable agent workflows available to the project.", "项目可用的可复用 Agent 工作流。"], + "Custom Agents": ["Specialized agent profiles available for delegated work.", "可用于委派工作的专用 Agent 配置。"], + Hooks: ["Lifecycle automation around agent and delivery events.", "围绕 Agent 与交付事件的生命周期自动化。"], + MCP: ["External tools and resources exposed through MCP.", "通过 MCP 暴露的外部工具与资源。"], + Commands: ["Named command entry points for repeatable agent work.", "可重复 Agent 工作的命令入口。"], + Workflows: ["Reusable multi-step project workflows.", "可复用的多步骤项目工作流。"], + Plugins: ["Installed packages that contribute agent capabilities.", "提供 Agent 能力的已安装插件。"], + "Session Insights": ["Task-session evidence available for report analysis.", "可用于报告分析的任务会话证据。"], + Memories: ["Representative project or global Memory note files.", "项目级或全局 Memory 的代表性笔记文件。"], + }; + const copy = descriptions[surface] ?? ["Recorded agent capability sources.", "已记录的 Agent 能力来源。"]; + return taskLoopCopy(copy[0], copy[1]); +} + +function TaskLoopPracticePaths({ paths }) { + if (paths.length === 0) return null; + const preview = paths.slice(0, 2); + const remaining = paths.slice(2); + return ( + + {preview.map((path, index) => ( + {path} + ))} + {remaining.length ? ( + + {taskLoopCopy(`View ${remaining.length} more locations`, `查看其余 ${remaining.length} 个位置`)} + + )} + bodyStyle={{ padding: "4px 0 0 16px" }} + headerStyle={{ borderBottom: "none", minHeight: 24 }} + > + + {remaining.map((path, index) => ( + {path} + ))} + + + ) : null} + + ); +} + +function PracticeSourceCard({ row }) { + const paths = visiblePracticePaths(row.paths); + const scopes = list(row.scopes); + return ( + + + + {row.surface ?? taskLoopCopy("Surface", "能力面")} + + )} + trailing={Number.isInteger(Number(row.count)) ? {row.count} : undefined} + /> + + + {practiceDescription(row.surface)} + {scopes.length || paths.length ? ( + + {scopes.length ? ( + + {scopes.map((scope) => {scope})} + + ) : null} + {paths.length ? ( + + {taskLoopCopy("Sources", "来源")} + + + ) : null} + + ) : null} + + + + ); +} + +function OpeningStrengths() { + const strengths = openingStrengths(); + return ( + + + {strengths.map((strength, index) => ( + {strength} + ))} + + + ); +} + +function DimensionSummary({ dimensions }) { + return ( + + {dimensions.map((row) => { + const score = clampScore(row.score); + return ( + + {taskLoopDimensionLabel(row.id)}} + trailing={{score}%} + /> + + + {textValue(row.summary) || DIMENSION_SUMMARY_EXAMPLE} + {list(row.findingRefs).length ? ( + Linked findings: {row.findingRefs.join(", ")} + ) : null} + + + + ); + })} + + ); +} + +function FindingItem({ row, dimensions }) { + return ( + + {row.title ?? row.id}} + trailing={{row.severity ?? "Unrated"}} + /> + + + + {list(row.dimensionRefs).slice(0, 1).map((ref) => ( + {dimensionLabel(ref, dimensions)} + ))} + + + + AI Fix + + + + + + ); +} + +function PracticeCoverage() { + const rows = practiceRows(); + const surfaces = inspectedSurfaces(); + + return ( + + + AI Agent Practices + {surfaces.length ? {surfaces.length} surfaces : null} + + {rows.length ? ( + + {rows.map((row, index) => )} + + ) : No AI Agent practice rows recorded.} + + ); +} + +function usesChineseReaderCopy() { + const locale = textValue(report.summary?.locale); + if (locale) return locale.toLowerCase().startsWith("zh"); + const readerSample = [ + ...list(report.summary?.strengths), + ...list(report.findings).slice(0, 3).flatMap((row) => [row?.title, row?.reason, row?.reader]), + ].map(textValue).join(" "); + return /[\u3400-\u9fff]/.test(readerSample); +} + +function taskLoopCopy(english, chinese) { + return usesChineseReaderCopy() ? chinese : english; +} + +function taskLoopDimensionLabel(id) { + if (!id) return taskLoopCopy("not observed", "未观察到"); + return dimensionLabel(id, list(report.summary?.dimensions)); +} + +function learningStateLabel(value) { + const labels = { + "N/A": ["Needs a comparison", "需要比较"], + pending: ["Comparison planned", "已计划比较"], + improving: ["Improving", "正在改善"], + unchanged: ["No clear change", "没有明显变化"], + regressing: ["Worse — stop or revert", "变差——停止或回退"], + "outcome-supported": ["A later result supports it", "后续结果支持它"], + }[value]; + return labels ? taskLoopCopy(labels[0], labels[1]) : taskLoopCopy("Not observed", "未观察到"); +} + +function taskLoopSummary() { + return report.summary?.atAGlance ?? {}; +} + +function taskLoopUsageActivity() { + const activity = report.summary?.usageActivity; + return activity && list(activity.dates).length ? activity : null; +} + +function taskLoopUsageEfficiency() { + const usage = report.summary?.usageEfficiency; + if (!usage || typeof usage !== "object" || Array.isArray(usage)) return null; + return usage.selection || usage.accounting || usage.longSessions || usage.modelUsage || usage.reviewLead + ? usage + : null; +} + +function usageSeriesTotal(series) { + return list(series).reduce((sum, row) => sum + Number(row?.total ?? 0), 0); +} + +function usageActivityMatrix(activity) { + const sourceDates = list(activity?.dates); + if (!sourceDates.length) return null; + const last = new Date(`${sourceDates.at(-1)}T00:00:00.000Z`); + const windowStart = new Date(last.getTime() - (364 * 86_400_000)); + const start = new Date(windowStart); + start.setUTCDate(start.getUTCDate() - start.getUTCDay()); + const weekCount = 53; + const columns = Array.from({ length: weekCount }, (_, index) => { + const date = new Date(start.getTime() + (index * 7 * 86_400_000)); + const previous = index > 0 ? new Date(start.getTime() + ((index - 1) * 7 * 86_400_000)) : null; + if (!previous || previous.getUTCMonth() === date.getUTCMonth()) return ""; + return usesChineseReaderCopy() + ? `${date.getUTCMonth() + 1}月` + : date.toLocaleDateString("en-US", { month: "short", timeZone: "UTC" }); + }); + const values = Array.from({ length: 7 }, () => Array(weekCount).fill(null)); + for (let dayOffset = 0; dayOffset < 365; dayOffset += 1) { + const date = new Date(windowStart.getTime() + (dayOffset * 86_400_000)); + const week = Math.floor((date.getTime() - start.getTime()) / (7 * 86_400_000)); + const dateKey = date.toISOString().slice(0, 10); + values[date.getUTCDay()][week] = { + id: dateKey, + value: 0, + ariaLabel: taskLoopCopy(`${dateKey}: no observed activity`, `${dateKey}:未观察到活动`), + }; + } + sourceDates.forEach((date, index) => { + const parsed = new Date(`${date}T00:00:00.000Z`); + const week = Math.floor((parsed.getTime() - start.getTime()) / (7 * 86_400_000)); + if (week < 0 || week >= weekCount) return; + const active = Number(activity?.sessions?.activeMinutes?.[index] ?? 0); + values[parsed.getUTCDay()][week] = { + id: date, + value: active, + ariaLabel: taskLoopCopy(`${date}: ${formatActivityMinutes(active)}`, `${date}:${formatActivityMinutes(active)}`), + }; + }); + return { columns, values, start: windowStart.toISOString().slice(0, 10), end: sourceDates.at(-1) }; +} + +function usageChartWindow(activity) { + const dates = list(activity?.dates); + const offset = Math.max(0, dates.length - 30); + return { offset, categories: dates.slice(offset).map((date) => String(date).slice(5)) }; +} + +function visibleUsageSeries(series, offset, limit = 5) { + const rows = list(series); + const named = rows.filter((row) => row?.name !== "Other"); + const primary = named.slice(0, limit).map((row) => ({ name: usageSeriesLabel(row.name), data: list(row.daily).slice(offset), total: Number(row.total ?? 0) })); + const remainder = [...named.slice(limit), ...rows.filter((row) => row?.name === "Other")]; + if (remainder.length > 0) { + const length = primary[0]?.data.length ?? list(remainder[0]?.daily).slice(offset).length; + primary.push({ + name: "Other", + total: remainder.reduce((sum, row) => sum + Number(row?.total ?? 0), 0), + data: Array.from({ length }, (_, index) => remainder.reduce((sum, row) => sum + Number(list(row?.daily).slice(offset)[index] ?? 0), 0)), + }); + } + return primary; +} + +function formatUsageNumber(value) { + return Math.round(Number(value ?? 0)).toLocaleString(usesChineseReaderCopy() ? "zh-CN" : "en-US"); +} + +function usageSeriesLabel(value) { + if (value === "Unknown model") return taskLoopCopy("Unattributed model", "未归属模型"); + if (value === "Unknown Skill") return taskLoopCopy("Unattributed Skill", "未归属 Skill"); + return value; +} + +function formatActivityMinutes(value) { + const formatted = Number(value ?? 0).toLocaleString(usesChineseReaderCopy() ? "zh-CN" : "en-US", { + maximumFractionDigits: 1, + }); + return `${formatted} ${taskLoopCopy("min", "分钟")}`; +} + +function taskLoopCoverage() { + return taskLoopSummary().coverage ?? {}; +} + +function confidenceLabel(value) { + const normalized = textValue(value).toLowerCase(); + const labels = { + high: ["High confidence", "高可信度"], + medium: ["Medium confidence", "中等可信度"], + low: ["Low confidence", "低可信度"], + }[normalized]; + return labels ? taskLoopCopy(labels[0], labels[1]) : taskLoopCopy("Confidence not recorded", "未记录可信度"); +} + +function confidenceTone(value) { + const normalized = textValue(value).toLowerCase(); + if (normalized === "high") return "success"; + if (normalized === "medium") return "warning"; + return "neutral"; +} + +function taskLoopStateLabel(value) { + const labels = { + Wired: ["Wired", "机制已接入"], + Present: ["Present", "已发现机制"], + Unobserved: ["Unobserved", "未观察到"], + observed: ["Observed", "已观察到"], + "Not applicable": ["Not applicable", "暂不适用"], + "N/A": ["Needs a comparison", "需要比较"], + }[value]; + return labels ? taskLoopCopy(labels[0], labels[1]) : textValue(value) || "—"; +} + +function taskLoopSubdimensionLabel(id) { + for (const dimension of list(report.summary?.dimensions)) { + const match = list(dimension?.subdimensions).find((row) => row?.id === id); + if (match) return match.label ?? id; + } + return id; +} + +function evidenceReferenceLabel(item) { + return textValue(item?.label) || textValue(item?.id) || taskLoopCopy("Unnamed evidence", "未命名证据"); +} + +function evidenceReferenceMeta(item) { + return [ + textValue(item?.status), + textValue(item?.type), + Number.isFinite(Number(item?.line)) ? `${taskLoopCopy("line", "行")} ${item.line}` : "", + ].filter(Boolean).join(" · "); +} + +function EvidenceReferenceList({ items }) { + return ( + + {items.map((item, index) => ( + + + {item?.group ? {item.group} : null} + {item?.kind ? {item.kind} : null} + {evidenceReferenceLabel(item)} + + {evidenceReferenceMeta(item) ? {evidenceReferenceMeta(item)} : null} + + ))} + + ); +} + +function severityLabel(value) { + const labels = { + Critical: ["Critical", "紧急"], + High: ["High", "高"], + Medium: ["Medium", "中"], + Low: ["Low", "低"], + }[value]; + return labels ? taskLoopCopy(labels[0], labels[1]) : value ?? "—"; +} + +function practiceSurfaceGlyph(surface) { + return ({ Rules: "R", Skills: "S", "Custom Agents": "A", Hooks: "H", MCP: "M" })[surface] ?? textValue(surface).slice(0, 1).toUpperCase() ?? "?"; +} + +function PracticeSurfaceIcon({ row }) { + return {practiceSurfaceGlyph(row?.surface)}; +} + +function TaskLoopReportHeader({ findings }) { + const sources = practiceRows().filter((row) => Number(row?.count) > 0); + const overview = textValue(report.summary?.overview); + return ( + +

{projectName()}

+ {overview ? {overview} : null} + + + {taskLoopCopy(`${findings.length} prioritized improvements`, `${findings.length} 项优先优化`)} + + {sources.length ? ( + + {taskLoopCopy(`${sources.length} practice source types`, `${sources.length} 类实践来源`)} + + ) : null} + +
+ ); +} + +function TaskLoopFluency({ dimensions }) { + if (dimensions.length === 0) return null; + return ( + + +

{taskLoopCopy("Agent Work Loop", "Agent 工作流")}

+ {dimensions.length} {taskLoopCopy("dimensions", "个维度")} +
+ + dimensionFluencyTooltip(dimensions[index])} + height={180} + highThreshold={70} + mediumThreshold={40} + showStageLabels + /> + +
+ ); +} + +function practiceCount(row) { + const value = Number(row?.count); + return Number.isInteger(value) ? value : "—"; +} + +function practiceScopeCell(row) { + const scopes = list(row?.scopes).map(textValue).filter(Boolean); + if (!scopes.length) return ; + return ( + + {scopes.map((scope) => {scope})} + + ); +} + +function practiceSourceCell(row) { + const [firstPath] = visiblePracticePaths(row?.paths); + return firstPath + ? {firstPath} + : {taskLoopCopy("No source location recorded", "未记录来源位置")}; +} + +function practiceSourceDetail(row) { + const remaining = visiblePracticePaths(row?.paths).slice(1); + if (!remaining.length) return null; + const pathListStyle = remaining.length > 8 + ? { maxHeight: 220, overflowY: "auto", paddingRight: 4 } + : { paddingRight: 4 }; + return ( + + {taskLoopCopy(`View ${remaining.length} more locations`, `查看其余 ${remaining.length} 个位置`)} + + )} + bodyStyle={{ padding: "6px 0 2px 16px" }} + headerStyle={{ borderBottom: "none", minHeight: 24 }} + > + + {remaining.map((path, index) => ( + {path} + ))} + + + ); +} + +function taskLoopPracticeColumns() { + return [ + { + key: "surface", + title: taskLoopCopy("Asset", "资产"), + minWidth: "300px", + render: (row) => ( + + + + {row.surface ?? taskLoopCopy("Surface", "能力面")} + + {practiceDescription(row.surface)} + + ), + }, + { + key: "coverage", + title: taskLoopCopy("Coverage", "覆盖范围"), + width: "170px", + minWidth: "150px", + render: (row) => ( + + + {taskLoopCopy(`${practiceCount(row)} sources`, `${practiceCount(row)} 个来源`)} + + {practiceScopeCell(row)} + + ), + }, + { + key: "source", + title: taskLoopCopy("Representative source", "代表来源"), + minWidth: "260px", + render: practiceSourceCell, + }, + ]; +} + +function TaskLoopPracticeTable({ rows = practiceRows() }) { + if (rows.length === 0) { + return {taskLoopCopy("No Agent assets recorded.", "未记录 Agent 工程资产。")}; + } + return ( + row.surface ?? "surface"} + density="compact" + renderDetail={practiceSourceDetail} + emptyText={taskLoopCopy("No Agent asset coverage recorded", "未记录 Agent 工程资产覆盖")} + /> + ); +} + +function TaskLoopActivityHeatmap({ activity }) { + const matrix = usageActivityMatrix(activity); + if (!matrix) return {taskLoopCopy("No dated session activity was observed.", "没有观察到带日期的会话活动。")}; + return ( + + + {taskLoopCopy("Daily activity (active minutes)", "每日活动(活跃分钟)")} + {matrix.start} — {matrix.end} + + formatActivityMinutes(value)} + cellSize={16} + columnWidth={16} + rowLabelWidth={34} + responsive + minCellSize={8} + minGap={2} + initialScrollPosition="end" + colorTemplate={{ + none: { background: "rgba(127, 127, 127, 0.1)", border: "transparent" }, + low: { background: "rgba(64, 166, 103, 0.22)", border: "transparent" }, + medium: { background: "rgba(54, 158, 94, 0.42)", border: "transparent" }, + high: { background: "rgba(38, 139, 78, 0.66)", border: "transparent" }, + critical: { background: "rgba(24, 115, 63, 0.9)", border: "transparent" }, + }} + maxHeight={190} + labels={{ ariaLabel: taskLoopCopy("Daily session activity", "每日会话活动") }} + /> + + ); +} + +function UsageStatRow({ label, value }) { + if (value === undefined || value === null || value === "") return null; + return ( + + {label} + {value} + + ); +} + +function UsageRankList({ series, limit = 5 }) { + const rows = list(series).slice(0, limit); + if (!rows.length) return {taskLoopCopy("No usage observed.", "未观察到用量。")}; + return ( + + {rows.map((row, index) => ( + + + {index + 1} + {usageSeriesLabel(row.name)} + + {formatUsageNumber(row.total)} + + ))} + + ); +} + +function taskLoopModelUsageColumns() { + return [ + { + key: "model", + title: taskLoopCopy("Model", "模型"), + minWidth: "180px", + render: (row) => {usageSeriesLabel(row.model)}, + }, + { + key: "responseCount", + title: taskLoopCopy("Responses", "响应数"), + width: "110px", + align: "right", + render: (row) => {formatUsageNumber(row.responseCount)}, + }, + { + key: "usageFieldObservedCount", + title: taskLoopCopy("Usage fields observed", "观察到用量字段"), + minWidth: "160px", + align: "right", + render: (row) => {formatUsageNumber(row.usageFieldObservedCount)}, + }, + { + key: "nonZeroUsageCount", + title: taskLoopCopy("Non-zero usage", "非零用量记录"), + minWidth: "140px", + align: "right", + render: (row) => {formatUsageNumber(row.nonZeroUsageCount)}, + }, + ]; +} + +function TaskLoopModelUsageTable({ rows }) { + if (!rows.length) return null; + return ( + + + {taskLoopCopy("Model response accounting", "模型响应明细")} + {rows.length} {taskLoopCopy("models", "个模型")} + + + {taskLoopCopy( + "These are response counts, not model-active session counts or a quality comparison.", + "这里统计的是响应次数,不是模型活跃会话数,也不代表模型质量对比。", + )} + +
row.model} + density="compact" + /> + + ); +} + +function TaskLoopLongSessionReview({ usage }) { + const lead = usage?.reviewLead; + const samples = list(usage?.longSessions?.samples); + if (!lead || !samples.length) return null; + const estimate = usage.longSessions?.estimate; + const coverage = lead.sampleCoverage; + const pendingCount = coverage?.shown ?? samples.length; + const analyzedCount = usage.selection?.analyzedSessionCount ?? 0; + const longestActiveMinutes = usage.longSessions?.longestActiveMinutes ?? Math.max(...samples.map((sample) => Number(sample.activeMinutes ?? 0))); + return ( + + + + +

{taskLoopCopy(`${pendingCount} long sessions need review`, `${pendingCount} 个长会话待复核`)}

+ {pendingCount} {taskLoopCopy("pending", "待复核")} +
+ + {taskLoopCopy( + `${pendingCount} of ${formatUsageNumber(analyzedCount)} analyzed sessions crossed the ${estimate?.activeThresholdMinutes ?? 45}-minute estimate threshold; the longest estimate is ${formatActivityMinutes(longestActiveMinutes)}. Treat them as investigation leads until reviewed.`, + `${formatUsageNumber(analyzedCount)} 个已分析会话中有 ${pendingCount} 个超过 ${estimate?.activeThresholdMinutes ?? 45} 分钟估算阈值,最长估算为 ${formatActivityMinutes(longestActiveMinutes)}。在人工复核前,只将其视为调查线索。`, + )} + +
+ + {taskLoopCopy(`Review ${pendingCount} sessions`, `复核 ${pendingCount} 个会话`)} + +
+ + {samples.map((sample, index) => { + const failureCount = Number(sample.failureCount ?? 0); + const roleLabel = sample.role === "user-thread-candidate" + ? taskLoopCopy("Main-thread candidate", "主线程候选") + : sample.role === "child-agent-candidate" + ? taskLoopCopy("Child-Agent candidate", "子 Agent 候选") + : sample.role; + return ( + + + + {sample.alias} + + {sample.userInputSummary} + {taskLoopCopy("Role", "角色")}: {roleLabel} + + + + {taskLoopCopy("Estimated active time", "估算活跃时长")} + {formatActivityMinutes(sample.activeMinutes)} + + + {formatUsageNumber(failureCount)} {taskLoopCopy("failures", "失败事件")} + + + {index < samples.length - 1 ? : null} + + ); + })} + + {estimate ? ( + + {taskLoopCopy( + `Estimate boundary: event gaps are capped at ${estimate.gapCapMinutes} minutes and gaps over ${estimate.idleGapMinutes} minutes are treated as idle.`, + `估算边界:事件间隔最多计 ${estimate.gapCapMinutes} 分钟,超过 ${estimate.idleGapMinutes} 分钟按空闲处理。`, + )} + + ) : null} +
+ ); +} + +function TaskLoopProjectUsage({ activity, usage }) { + if (!activity && !usage) return null; + const activeMinutes = list(activity?.sessions?.activeMinutes).reduce((sum, value) => sum + Number(value ?? 0), 0); + const census = usage?.selection; + const longSessions = usage?.longSessions; + const skillUses = usageSeriesTotal(activity?.skills); + const analyzedSessions = census + ? `${formatUsageNumber(census.analyzedSessionCount)} / ${formatUsageNumber(census.eligibleSessionCount)}` + : activity ? formatUsageNumber(activity.sessions?.total) : null; + return ( + + {activity ? : null} + {activity ? : null} + + + {taskLoopCopy("Activity insights", "使用概览")} + + {activity ? : null} + {activity ? : null} + {longSessions ? : null} + + + {taskLoopCopy("Most used Skills", "最常使用的 Skills")} + + + + + ); +} + +function TaskLoopUsageMethodology({ usage }) { + if (!usage) return null; + const census = usage.selection; + const accounting = usage.accounting; + const roles = usage.roles; + const outcomeReview = usage.outcomeReview; + const taskSelection = taskLoopCoverage().selection ?? {}; + const modelUsage = list(usage.modelUsage); + const hasCoverage = census || Object.keys(taskSelection).length || roles || accounting; + if (!hasCoverage && !modelUsage.length && !usage.reviewLead) return null; + + return ( + + {census || Object.keys(taskSelection).length ? ( + + {taskLoopMeasurementBoundaryText(taskSelection, census)} + + ) : null} + {roles || accounting ? ( + + {roles ? ( + + {taskLoopCopy("Session composition", "会话构成")} + + + + ) : null} + {accounting ? ( + + {taskLoopCopy("Measurement coverage", "计量覆盖")} + + + + + + + ) : null} + + ) : null} + {modelUsage.length ? : null} + + {accounting?.mode === "effort-proxy" + ? taskLoopCopy("Active time and model-session counts are effort proxies; exact token or credit savings are unavailable.", "活跃时间和模型会话数仅代表投入;目前无法精确计算 token 或 credit 节省。") + : taskLoopCopy("Usage totals describe observed activity, not counterfactual savings.", "用量只描述已观察活动,不代表反事实节省。")} + {outcomeReview && !outcomeReview.comparableModelOutcomeEvidence + ? taskLoopCopy(" Model outcomes need a controlled A/B before comparison.", " 模型效果需要通过受控 A/B 后才能比较。") + : ""} + + + ); +} + +function usageTrendLeader(series) { + return series.reduce((leader, row) => Number(row.total ?? 0) > Number(leader?.total ?? -1) ? row : leader, null); +} + +function usageTrendRange(categories) { + if (!categories.length) return taskLoopCopy("Latest observations", "最近观测"); + if (categories.length === 1) return categories[0]; + return `${categories[0]} – ${categories[categories.length - 1]}`; +} + +function TaskLoopUsageTrend({ title, totalLabel, leaderDescription, series, categories }) { + if (!series.length) return null; + const total = series.reduce((sum, row) => sum + Number(row.total ?? 0), 0); + const leader = usageTrendLeader(series); + const range = usageTrendRange(categories); + return ( + + + + + {title} + + {taskLoopCopy( + `${range} · ${formatUsageNumber(total)} ${totalLabel}`, + `${range} · 共 ${formatUsageNumber(total)} ${totalLabel}`, + )} + + + + {leader ? ( + + {usageSeriesLabel(leader.name)} · {formatUsageNumber(leader.total)} {totalLabel} + {leaderDescription} + + ) : null} + + + + ); +} + +function TaskLoopUsageTrends({ activity }) { + if (!activity) return null; + const chartWindow = usageChartWindow(activity); + const categories = chartWindow.categories; + const modelSeries = visibleUsageSeries(activity.models, chartWindow.offset); + const skillSeries = visibleUsageSeries(activity.skills, chartWindow.offset); + if (!modelSeries.length && !skillSeries.length) return null; + return ( + +

{taskLoopCopy("Usage trends", "用量趋势")}

+ + + + +
+ ); +} + +function taskLoopSessionInsightTitle(id) { + const labels = { + "session-insight:source-coverage": ["Source coverage", "数据覆盖"], + "session-insight:validation-behavior": ["Validation behavior", "验证行为"], + "session-insight:post-edit-validation": ["Post-edit validation", "改动后验证"], + "session-insight:execution-friction": ["Execution friction", "执行摩擦"], + "session-insight:tool-mix": ["Tool mix", "工具使用"], + "session-insight:observed-hooks": ["Observed hooks", "Hook 执行"], + "session-insight:planning-workflow": ["Planning workflow", "规划工作流"], + "session-insight:session-complexity": ["Session complexity", "会话复杂度"], + "session-insight:session-usage-efficiency": ["Session effort", "会话投入"], + }[id]; + return labels ? taskLoopCopy(labels[0], labels[1]) : id; +} + +function taskLoopSessionInsightConfidence(row) { + return list(row?.labels).map(textValue).find((value) => ["High", "Medium", "Low"].includes(value)) ?? ""; +} + +function taskLoopSessionInsightColumns() { + return [ + { + key: "id", + title: taskLoopCopy("Observation", "观察主题"), + minWidth: "150px", + render: (row) => {taskLoopSessionInsightTitle(row.id)}, + }, + { + key: "summary", + title: taskLoopCopy("What was observed", "观察说明"), + minWidth: "420px", + render: (row) => {row.summary ?? "—"}, + }, + { + key: "confidence", + title: taskLoopCopy("Confidence", "可信度"), + minWidth: "120px", + render: (row) => { + const confidence = taskLoopSessionInsightConfidence(row); + return confidence ? {confidenceLabel(confidence)} : ; + }, + }, + { + key: "evidenceRefs", + title: taskLoopCopy("Evidence", "证据"), + width: "80px", + align: "right", + render: (row) => {list(row.evidenceRefs).length}, + }, + ]; +} + +function taskLoopSessionInsightDetail(row) { + const evidenceRefs = list(row?.evidenceRefs); + return ( + {taskLoopCopy("View raw observation metadata", "查看原始观察元数据")}} + bodyStyle={{ padding: "6px 0 2px 16px" }} + headerStyle={{ borderBottom: "none", minHeight: 24 }} + > + + + {taskLoopCopy("Insight ID", "洞察 ID")}: {row.id} · {taskLoopCopy("Status", "状态")}: {row.status ?? "—"} · {taskLoopCopy("Kind", "类型")}: {row.kind ?? "—"} · {taskLoopCopy("Model", "模型版本")}: {row.modelVersion ?? "—"} + + {list(row.labels).length ? ( + {row.labels.map((label) => {label})} + ) : null} + {evidenceRefs.length ? : {taskLoopCopy("No raw evidence references recorded.", "未记录原始证据引用。")}} + + + ); +} + +function taskLoopRepresentativeSessionInsights(entries) { + const preferredIds = [ + "session-insight:post-edit-validation", + "session-insight:execution-friction", + "session-insight:tool-mix", + ]; + const preferred = preferredIds + .map((id) => entries.find((entry) => entry?.id === id)) + .filter((entry) => entry && list(entry.evidenceRefs).length > 0); + const remaining = entries + .filter((entry) => list(entry?.evidenceRefs).length > 0 && !preferred.includes(entry)) + .sort((left, right) => list(right.evidenceRefs).length - list(left.evidenceRefs).length); + return [...preferred, ...remaining].slice(0, 3); +} + +function TaskLoopSessionInsightsDialog({ entries }) { + return ( + + {taskLoopCopy(`View all ${entries.length}`, `查看全部 ${entries.length} 条`)} + + )} + title={taskLoopCopy("All session observations", "全部会话观察")} + closeLabel={taskLoopCopy("Close", "关闭")} + maxWidth={1040} + > + + + {taskLoopCopy( + "These are candidate observations projected from session evidence. Read them as investigation leads, not confirmed user intent or outcome claims.", + "这些是从会话证据投影出的候选观察,用于指引后续调查,不等同于已确认的用户意图或结果结论。", + )} + +
row.id} + density="compact" + renderDetail={taskLoopSessionInsightDetail} + /> + + + ); +} + +function TaskLoopSessionInsights() { + const entries = list(report.summary?.semanticFacets?.entries); + if (!entries.length) return null; + const representativeEntries = taskLoopRepresentativeSessionInsights(entries); + const rowTones = ["success", "warning", "info"]; + return ( + + +

{taskLoopCopy("Session observations", "会话观察")}

+ {entries.length} {taskLoopCopy("observations", "条观察")} +
+ + {taskLoopCopy( + "Representative evidence-bearing observations for follow-up investigation and priority judgment.", + "按主题呈现的代表性观察,用于指引后续调查与优先级判断。", + )} + + + {representativeEntries.map((row, index) => { + const confidence = taskLoopSessionInsightConfidence(row); + const evidenceCount = list(row.evidenceRefs).length; + return ( + + + + + {index + 1} + {taskLoopSessionInsightTitle(row.id)} + + + {row.summary ?? "—"} + + + {confidence ? {confidenceLabel(confidence)} : null} + + {evidenceCount} {taskLoopCopy(evidenceCount === 1 ? "evidence item" : "evidence items", "条证据")} + + + + + + ); + })} + + + + +
+ ); +} + +function TaskLoopFindingDialog({ row }) { + const expectedOutput = list(row.expectedOutput).filter((item) => textValue(item)); + const dimensionRefs = list(row.dimensionRefs); + return ( + {taskLoopCopy("View details", "查看详情")} + )} + title={row.title ?? row.id} + closeLabel={taskLoopCopy("Close", "关闭")} + maxWidth={880} + footer={( + + + {taskLoopCopy("Plan AI Fix", "规划 AI 修复")} + + + )} + > + + + {severityLabel(row.severity)} + {dimensionRefs.map((dimensionRef) => ( + {taskLoopDimensionLabel(dimensionRef)} + ))} + + + {taskLoopCopy("Cause", "原因")} + + {textValue(row.reason) || taskLoopCopy("No cause was recorded.", "未记录原因。")} + + + + + {taskLoopCopy("Expected Output", "预期结果")} + {expectedOutput.length ? expectedOutput.map((output, index) => ( + + {index + 1} + {output} + + )) : ( + {taskLoopCopy("No expected output was recorded.", "未记录预期结果。")} + )} + + + + ); +} + +function TaskLoopFindingCard({ row }) { + const [dimensionRef] = list(row.dimensionRefs); + return ( + + + + + + {severityLabel(row.severity)} + {dimensionRef ? {taskLoopDimensionLabel(dimensionRef)} : null} + + + {row.title ?? row.id} + + {textValue(row.reason) ? ( + + {row.reason} + + ) : null} + + + + + + {taskLoopCopy("Plan AI Fix", "规划 AI 修复")} + + + + + + + + ); +} + +function TaskLoopFindingCards({ findings }) { + return ( + + {findings.map((row) => )} + + ); +} + +function taskLoopSuggestionKindLabel(kind) { + const labels = { + "try-existing": ["Try existing", "试用已有能力"], + "working-pattern": ["Working pattern", "有效模式"], + "loop-candidate": ["Loop candidate", "循环候选"], + horizon: ["Horizon", "中长期"], + }[kind] ?? ["Suggestion", "建议"]; + return taskLoopCopy(labels[0], labels[1]); +} + +function TaskLoopSuggestionDialog({ row }) { + const prerequisites = list(row.prerequisites).map(textValue).filter(Boolean); + const blockedBy = list(row.blockedBy).map(textValue).filter(Boolean); + return ( + {taskLoopCopy("Review suggestion", "查看建议")}} + title={row.title ?? row.id} + closeLabel={taskLoopCopy("Close", "关闭")} + maxWidth={760} + > + + + {taskLoopSuggestionKindLabel(row.kind)} + {confidenceLabel(row.confidence)} + + + {taskLoopCopy("Why this is worth trying", "为什么值得尝试")} + {row.reason} + + + + + {taskLoopCopy("Owner", "负责人")} + {row.owner} + + + {taskLoopCopy("Validation", "验证")} + {row.validation} + + + + {taskLoopCopy("Next step", "下一步")} + {row.nextStep} + + {prerequisites.length ? ( + + {taskLoopCopy("Prerequisites", "前置条件")} + {prerequisites.map((item, index) => ( + + {index + 1} + {item} + + ))} + + ) : null} + {blockedBy.length ? ( + + {taskLoopCopy("Blocked by", "阻塞项")} + {blockedBy.map((item, index) => ( + + {index + 1} + {item} + + ))} + + ) : null} + + + ); +} + +function TaskLoopSuggestionCard({ row }) { + return ( + + + + + {taskLoopSuggestionKindLabel(row.kind)} + {confidenceLabel(row.confidence)} + + + {row.title ?? row.id} + + + {row.reason} + + + {taskLoopCopy("Next step", "下一步")} + {row.nextStep} + + + + {row.owner} + + + + + + ); +} + +function TaskLoopSuggestionCards({ suggestions }) { + return ( + + {suggestions.map((row) => )} + + ); +} + +function taskLoopDeliveryOutcomeLabel(boundary) { + if (!boundary || !Object.hasOwn(boundary, "deliveryEvidenceLevels")) { + return taskLoopCopy("Not supplied", "未提供"); + } + const levels = list(boundary?.deliveryEvidenceLevels).map(textValue).filter(Boolean); + if (!levels.length || levels.every((value) => ["none", "unobserved", "not-observed"].includes(value.toLowerCase()))) { + return taskLoopCopy("Not observed", "未观察到"); + } + return levels.join(", "); +} + +function taskLoopCoverageFraction(value, analyzedField, eligibleField) { + if (!value || !Object.hasOwn(value, analyzedField) || !Object.hasOwn(value, eligibleField)) return null; + const analyzed = Number(value[analyzedField]); + const eligible = Number(value[eligibleField]); + return Number.isInteger(analyzed) && analyzed >= 0 && Number.isInteger(eligible) && eligible >= 0 + ? `${formatUsageNumber(analyzed)}/${formatUsageNumber(eligible)}` + : null; +} + +function taskLoopMeasurementBoundaryText(selection, usageSelection) { + const sample = taskLoopCoverageFraction(selection, "analyzedCount", "eligibleCount"); + const activity = taskLoopCoverageFraction(usageSelection, "analyzedSessionCount", "eligibleSessionCount"); + if (sample && activity) { + return taskLoopCopy( + `Work-stage conclusions use ${sample} stratified sample sessions; activity accounting covers ${activity}. Use this evidence to locate review leads, not to prove efficiency or model quality.`, + `工作环节结论来自 ${sample} 个分层抽样会话;活动统计覆盖 ${activity}。当前证据可用于定位线索,不足以证明效率或模型质量。`, + ); + } + if (sample) { + return taskLoopCopy( + `Work-stage conclusions use ${sample} stratified sample sessions. Activity and model accounting were not supplied, so no usage conclusion is available.`, + `工作环节结论来自 ${sample} 个分层抽样会话。未提供活动与模型统计,因此无法形成用量结论。`, + ); + } + if (activity) { + return taskLoopCopy( + `Activity accounting covers ${activity}. Sampling provenance was not supplied, so usage is shown without a work-stage sampling conclusion.`, + `活动统计覆盖 ${activity}。未提供抽样来源,因此这里只展示用量,不形成工作环节抽样结论。`, + ); + } + return taskLoopCopy( + "Session measurement context was not supplied, so no sampling, usage, or model conclusion is available.", + "未提供会话计量上下文,因此无法形成抽样、用量或模型结论。", + ); +} + +function taskLoopMeasurementModelLabel(usage, modelUsage) { + if (!usage) return taskLoopCopy("Usage unavailable", "用量不可用"); + return `${modelUsage.length} ${taskLoopCopy("models", "个模型")}`; +} + +function taskLoopSelectionDetailText(selection) { + const coverage = taskLoopCoverageFraction(selection, "analyzedCount", "eligibleCount"); + if (!coverage) return taskLoopCopy("Not supplied", "未提供"); + return taskLoopCopy( + `${textValue(selection.strategy) || "unknown"}; ${coverage} eligible sessions analyzed.`, + `${textValue(selection.strategy) || "未知"};已分析 ${coverage} 个符合条件的会话。`, + ); +} + +function taskLoopTaskEvidenceText(coverage) { + const fields = ["episodeCount", "editedEpisodeCount", "closedEpisodeCount", "recoveredEpisodeCount"]; + if (!fields.every((field) => Object.hasOwn(coverage, field))) return taskLoopCopy("Not supplied", "未提供"); + const [episodes, edited, closed, recovered] = fields.map((field) => Number(coverage[field])); + if (![episodes, edited, closed, recovered].every((value) => Number.isInteger(value) && value >= 0)) { + return taskLoopCopy("Not supplied", "未提供"); + } + return taskLoopCopy( + `${episodes} episodes; ${edited} with changes; ${closed} closed; ${recovered} repaired and passed.`, + `${episodes} 个任务片段;${edited} 个包含改动;${closed} 个已闭环;${recovered} 个修复并通过。`, + ); +} + +function taskLoopLearningDetailText(learning) { + if (!Object.hasOwn(learning, "state") && !Array.isArray(learning.interventions)) { + return taskLoopCopy("Not supplied", "未提供"); + } + return taskLoopCopy( + `${learningStateLabel(learning.state)}; ${list(learning.interventions).length} declared intervention(s).`, + `${learningStateLabel(learning.state)};${list(learning.interventions).length} 项已声明的改进。`, + ); +} + +function TaskLoopEvidenceFact({ label, value, tone = "neutral" }) { + return ( + + + + {label} + + {value} + + + + + ); +} + +function TaskLoopEvidenceDetails({ usage, boundary, manifest, selection, learning, coverage }) { + const hasDetailedBoundary = Object.keys(boundary).length > 0 + || Object.keys(coverage).length > 0 + || Object.keys(learning).length > 0; + return ( + + {hasDetailedBoundary ? ( + + {taskLoopCopy("Sampling and provenance", "抽样与来源")} + {taskLoopCopy("Session selection", "会话抽样")}: {taskLoopSelectionDetailText(selection)} + {taskLoopCopy("Task evidence", "任务证据")}: {taskLoopTaskEvidenceText(coverage)} + {taskLoopCopy("Delivery outcomes", "交付结果")}: {taskLoopDeliveryOutcomeLabel(boundary)}. + {taskLoopCopy("Learning comparison", "学习循环比较")}: {taskLoopLearningDetailText(learning)} + {textValue(learning.summary) ? {learning.summary} : null} + + ) : ( + + {taskLoopCopy( + "This run did not supply task-episode or delivery-outcome evidence, so the report only shows repository signals it could verify.", + "本次运行没有提供任务片段或交付结果证据,因此报告只展示能够验证的仓库信号。", + )} + + )} + + + + + + + + + {usage ? ( + <> + + + + ) : null} + + ); +} + +function TaskLoopEvidenceBoundary({ usage }) { + const boundary = report.summary?.evidenceBoundary ?? {}; + const manifest = boundary.manifest ?? {}; + const selection = manifest.selection ?? {}; + const learning = report.summary?.learningCapture ?? {}; + const coverage = taskLoopCoverage(); + const modelUsage = list(usage?.modelUsage); + const longSessionSamples = list(usage?.longSessions?.samples); + const sessionInsights = list(report.summary?.semanticFacets?.entries); + const activitySelection = usage?.selection ?? {}; + const samplingConfidence = textValue(selection.confidence) + || taskLoopCopy("Not supplied", "未提供"); + const sourceGapValue = Array.isArray(boundary.sourceGaps) ? boundary.sourceGaps.length : "—"; + + return ( + +

{taskLoopCopy("Evidence and methodology", "证据与方法")}

+ + + {taskLoopMeasurementBoundaryText(selection, activitySelection)} + + + + + + + + {usage?.reviewLead && longSessionSamples.length ? ( + <> + + + + ) : null} + {sessionInsights.length ? ( + <> + + + + ) : null} + + + {taskLoopCopy("View measurement and model details", "查看计量与模型明细")} + + {taskLoopCopy("Response accounting, model detail, and sampling method", "响应计量、模型明细与抽样方法")} + + + )} + trailing={{taskLoopMeasurementModelLabel(usage, modelUsage)}} + bodyStyle={{ padding: "12px 0 2px 16px" }} + headerStyle={{ minHeight: 44 }} + > + + +
+ ); +} + +function TaskLoopReport() { + const dimensions = list(report.summary?.dimensions); + const findings = list(report.findings).sort((left, right) => severityRank(left.severity) - severityRank(right.severity)); + const suggestions = list(report.summary?.suggestions); + const activity = taskLoopUsageActivity(); + const usage = taskLoopUsageEfficiency(); + const highFindings = findings.filter((row) => row.severity === "Critical" || row.severity === "High"); + const mediumFindings = findings.filter((row) => row.severity === "Medium"); + return ( + + + + + + {activity || usage ? ( + +

{taskLoopCopy("Project usage", "项目用量")}

+ +
+ ) : null} + + + +

{taskLoopCopy("Prioritized improvements", "优先优化项")}

+ + {taskLoopCopy( + `${findings.length} total · ${highFindings.length} high · ${mediumFindings.length} medium`, + `共 ${findings.length} 项 · ${highFindings.length} 个高优先级 · ${mediumFindings.length} 个中优先级`, + )} + +
+ + {suggestions.length ? ( + <> + + + + {taskLoopCopy("Suggestions", "建议")} + + {taskLoopCopy( + "Evidence-bound capabilities and patterns worth trying next. Suggestions are advisory and do not include an AI Fix action.", + "基于证据、值得下一步尝试的能力与模式。建议仅供参考,不包含 AI 修复动作。", + )} + + + {suggestions.length} {taskLoopCopy("suggestions", "条建议")} + + + + ) : null} +
+ + +

{taskLoopCopy("Agent Customize", "Agent 自定义")}

+ + {taskLoopCopy( + "Discovered sources, not a quality or maturity score.", + "这里只展示已发现来源,不代表质量或成熟度评分。", + )} + + +
+ + + + +
+ ); +} + +export default function QoderHarnessReport() { + return ; +} diff --git a/.qoder/better-loop/2026-07-23/011632-applyguard-ph/canvas.json b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/canvas.json new file mode 100644 index 0000000..08deeb0 --- /dev/null +++ b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/canvas.json @@ -0,0 +1,89 @@ +{ + "schemaVersion": 1, + "summaryFactsSchemaVersion": 1, + "summary": { + "evidenceMode": "session-limited", + "evidenceBoundary": { + "manifest": { + "schemaVersion": 2, + "sourceFingerprint": "c230073388d2d558", + "adapterVersion": "qoder-task-loop-source-v2", + "platform": "qoder", + "selection": { + "strategy": "all-eligible", + "eligibleCount": 0, + "analyzedCount": 0, + "confidence": "Low" + } + }, + "deliveryEvidenceLevels": [], + "sourceGaps": [] + }, + "semanticFacets": { + "schemaVersion": 1, + "status": "supplementary", + "entries": [ + { + "id": "session-insight:source-coverage", + "kind": "redacted-summary", + "episodeRef": null, + "status": "candidate", + "labels": [ + "source-coverage", + "Low" + ], + "summary": "Analyzed 0 of 0 sessions; 0/5 enabled source roots exist. Use this as the current workspace evidence boundary for final insight cards.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + }, + { + "id": "session-insight:validation-behavior", + "kind": "redacted-summary", + "episodeRef": null, + "status": "candidate", + "labels": [ + "validation-behavior", + "Low" + ], + "summary": "No validation command category was observed in the analyzed session sample. Inspect more sessions or add explicit validation guidance before claiming validation-after-edit behavior.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + }, + { + "id": "session-insight:post-edit-validation", + "kind": "rework-correction", + "episodeRef": null, + "status": "candidate", + "labels": [ + "post-edit-validation", + "Low" + ], + "summary": "No edit event was observed in the analyzed sample. Inspect more sessions before making claims about edit or validation habits.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + }, + { + "id": "session-insight:execution-friction", + "kind": "friction-taxonomy", + "episodeRef": null, + "status": "candidate", + "labels": [ + "execution-friction", + "Low" + ], + "summary": "No strong execution friction signal in the analyzed sample. Keep friction claims narrow unless additional failed commands, rejected actions, or warnings are inspected.", + "evidenceRefs": [], + "modelVersion": "session-insights-v1" + } + ] + }, + "learningCapture": { + "schemaVersion": 1, + "state": "N/A", + "summary": "N/A — requires two comparable observation windows and an intervention comparison.", + "interventions": [] + } + }, + "dimensions": [], + "findings": [] +} diff --git a/.qoder/better-loop/2026-07-23/011632-applyguard-ph/findings.json b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/findings.json new file mode 100644 index 0000000..e7b7c82 --- /dev/null +++ b/.qoder/better-loop/2026-07-23/011632-applyguard-ph/findings.json @@ -0,0 +1,163 @@ +{ + "summary": { + "projectName": "ApplyGuard PH", + "locale": "en", + "modelId": "agent-work-loop-v4", + "reportContractVersion": 24, + "overview": "ApplyGuard PH has a clear public README, 10 unit-test files for pure-logic modules, and a Supabase CI pipeline, but lacks agent-oriented guidance, environment pinning, and delivery-side validation, making agent work heavily reliant on implicit knowledge and unchecked changes.", + "dimensions": [ + { + "id": "task-understanding", + "label": "Task Understanding", + "score": 45, + "summary": "Human-oriented README covers architecture well, but no agent entrypoint (AGENTS.md, CLAUDE.md) exists; risk areas and task routes are undocumented for agent readers." + }, + { + "id": "controlled-execution", + "label": "Controlled Execution", + "score": 60, + "summary": "Package.json scripts are clear and lockfile is present, but no .nvmrc, no devcontainer, and no state-reset or doctor commands; environment assumptions remain partly implicit." + }, + { + "id": "change-validation", + "label": "Change Validation", + "score": 52, + "summary": "10 well-structured unit-test files cover core logic; however, no fast/slow test separation, no integration or E2E tests, and CI does not run the test suite before deployment." + }, + { + "id": "reliable-delivery", + "label": "Reliable Delivery", + "score": 48, + "summary": "Supabase Edge Function CI enforces deployment, but frontend has no CI gate; payment verification has server-side validation but no observable rollback plan or approval path for agent-produced changes." + }, + { + "id": "learning-capture", + "label": "Learning Capture", + "score": 35, + "summary": "No .qoder directory, project skills, hooks, or memory configuration; the reviewed window is clean of candidates but also lacks any mechanism for lifecycle detection or reuse." + } + ], + "aiAgentPractice": { + "inspectedSurfaces": ["Rules", "Skills", "Hooks"], + "coverageRows": [ + { + "surface": "Rules", + "scopes": ["Project"], + "count": 0, + "paths": [] + }, + { + "surface": "Skills", + "scopes": ["Project"], + "count": 0, + "paths": [] + }, + { + "surface": "Hooks", + "scopes": ["Project", "Global"], + "count": 0, + "paths": [] + } + ] + }, + "suggestions": [ + { + "id": "scaffold-agent-entrypoint", + "kind": "loop-candidate", + "title": "Create an agent entrypoint (AGENTS.md)", + "reason": "The project has no agent-oriented guidance; adding an entrypoint would let agents find the right context, risk areas, and test routes without manual discovery or human handoffs.", + "confidence": "Medium", + "owner": "Project maintainer", + "nextStep": "Write a short AGENTS.md (80-120 lines) that maps source directories, identifies high-risk areas (payments, data deletion, auth), and lists validation commands by scope.", + "validation": "Agent can open AGENTS.md and find the correct test command, deployment path, and payment-risk warning." + }, + { + "id": "add-test-ci-gate", + "kind": "loop-candidate", + "title": "Add Vitest run to CI workflow", + "reason": "The Supabase CI deploys edge functions but never runs the frontend test suite; a test failure on main has no automated safety net.", + "confidence": "High", + "owner": "Project maintainer", + "nextStep": "Add a `npm test` step to .github/workflows/supabase.yml before deployment, or create a separate frontend CI workflow.", + "validation": "Pushing a failing test to a PR branch produces a non-zero exit and visible CI failure." + }, + { + "id": "pin-node-version", + "kind": "try-existing", + "title": "Add .nvmrc for reproducible runtime", + "reason": "Netlify uses NODE_VERSION=20 in netlify.toml, but no project-level pin exists for local or CI environments, creating implicit version assumptions.", + "confidence": "High", + "owner": "Project maintainer", + "nextStep": "Create .nvmrc with the Node version that matches netlify.toml (20) and verify local dev still works.", + "validation": "`node --version` matches the pinned version after `nvm use` (or the agent reads .nvmrc before install commands)." + } + ] + }, + "findings": [ + { + "id": "agent-instructions-missing", + "title": "No agent entrypoint or scoped guidance for task routing", + "severity": "High", + "reason": "The project has no AGENTS.md, CLAUDE.md, or equivalent agent guidance. The README (148 lines) serves a human audience. An agent must infer project boundaries, risk areas (payment verification, data deletion, AI proxy keys), and validation routes by scanning the full repository, which increases the chance of incorrect scope, missing test requirements, or unsafe operations.", + "dimensionRefs": ["task-understanding"], + "expectedArtifact": "AGENTS.md", + "expectedOutput": [ + "Add AGENTS.md with directory map, risk areas, validations-per-scope, and deployment notes.", + "Agent can find the correct test command, deployment path, and payment-risk warning from the entrypoint." + ], + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a project-level AGENTS.md that maps src/ and supabase/ directories, flags high-risk areas (payment verification, data deletion, auth), and lists validation commands by scope." + }, + { + "id": "no-frontend-ci-validation", + "title": "Frontend unit tests never run in CI", + "severity": "High", + "reason": "The only CI workflow (supabase.yml) deploys Supabase Edge Functions but does not run `npm test` for the 10 frontend unit-test files. A regression in core scoring, red-flag, or entitlement logic can reach main without automated detection.", + "dimensionRefs": ["change-validation"], + "expectedArtifact": ".github/workflows/supabase.yml", + "expectedOutput": [ + "Add test step (npm test) to CI workflow.", + "Pushing a failing test produces a non-zero exit and visible CI failure." + ], + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a `npm test` step before the deployment steps in .github/workflows/supabase.yml so that unit tests run on every push to the supabase/functions path." + }, + { + "id": "missing-runtime-pin", + "title": "Node.js runtime version not pinned at project root", + "severity": "Medium", + "reason": "Netlify config pins NODE_VERSION=20 in netlify.toml, but there is no .nvmrc or .tool-versions at the project root. Package.json engines field is absent. This creates implicit, unverifiable runtime assumptions for local dev and CI environments.", + "dimensionRefs": ["controlled-execution"], + "expectedArtifact": ".nvmrc", + "expectedOutput": [ + "Create .nvmrc with Node engine version matching netlify.toml (20.x).", + "Explicit runtime constraint for agent setup and CI." + ], + "aiFixPrompt": "/better-loop fix this issue\n\nCreate a .nvmrc file matching the Node version from netlify.toml (NODE_VERSION = \"20\")." + }, + { + "id": "no-integration-e2e-tests", + "title": "No integration or E2E test coverage for critical user flows", + "severity": "Medium", + "reason": "All 10 test files are unit tests targeting pure functions. The scan → score → verdict → save flow, cloud sync, payment flows, and SPA routing have no integration or E2E coverage. An agent changing React components, routing, or storage has no automated way to verify the end-to-end behavior still works.", + "dimensionRefs": ["change-validation"], + "expectedArtifact": "Integration test file(s)", + "expectedOutput": [ + "Add integration test covering the end-to-end scan flow.", + "Agent can run a flow-level test to validate behavior after changes." + ], + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a Playwright or Vitest integration test for the scan→score→verdict→save flow. Place it at src/lib/flow.test.js and verify it exercises the core pipeline." + }, + { + "id": "no-recovery-plan-for-payment-state", + "title": "Payment and data-deletion recovery has no documented owner route", + "severity": "Medium", + "reason": "The project handles live PayPal payments and user data in Supabase. The README describes server-side verification and webhook fulfillment, but there is no documented rollback, recovery, or escalation plan for agent-facing payment operations, failed captures, or accidental data deletion. An agent has no owned route to follow on recovery.", + "dimensionRefs": ["reliable-delivery"], + "expectedArtifact": "Recovery documentation", + "expectedOutput": [ + "Add recovery/rollback documentation covering payment capture failure, webhook reconciliation, and data restoration.", + "Agent can find the owned recovery route after a payment failure." + ], + "aiFixPrompt": "/better-loop fix this issue\n\nAdd a recovery section either in a new AGENTS.md or docs/ directory that covers: (1) what to do on PayPal capture failure, (2) how to reconcile webhook delivery gaps, (3) how to restore user data from Supabase. Keep it actionable for an agent operator." + } + ] +} diff --git a/.qoder/repowiki/en/content/API Reference/API Reference.md b/.qoder/repowiki/en/content/API Reference/API Reference.md new file mode 100644 index 0000000..155b2fb --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/API Reference.md @@ -0,0 +1,662 @@ +# API Reference + + +**Referenced Files in This Document** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/auth.jsx](file://src/auth.jsx) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion + +## Introduction +This document provides a comprehensive API reference for ApplyGuard PH’s backend services hosted on Supabase Edge Functions. It covers: +- HTTP endpoints for billing, subscriptions, and AI proxying +- Webhook interfaces for payment processors (PayMongo and PayPal) +- Authentication requirements and shared utilities +- Security headers, rate limiting considerations, and versioning strategies +- Client integration patterns using the frontend SDKs and libraries +- Error handling and troubleshooting guidance + +The goal is to enable developers to integrate securely and reliably with the backend services. + +## Project Structure +The backend is implemented as Supabase Edge Functions under supabase/functions. Shared logic resides in supabase/functions/_shared. Database schema and migrations are under supabase/migrations. The frontend client code integrates via src/lib modules and auth flows. + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +A["create-checkout/index.ts"] +B["cancel-subscription/index.ts"] +C["capture-paypal-order/index.ts"] +D["create-paypal-order/index.ts"] +E["paymongo-webhook/index.ts"] +F["paypal-webhook/index.ts"] +G["ai-proxy/index.ts"] +H["download-message-pack/index.ts"] +S1["_shared/http.ts"] +S2["_shared/entitlement.ts"] +S3["_shared/paypal.ts"] +S4["_shared/paypal-runtime.ts"] +end +subgraph "Database" +DB["PostgreSQL
migrations/001_schema.sql
migrations/002_paypal_fulfillment.sql"] +end +subgraph "Frontend" +CL1["src/lib/supabase.js"] +CL2["src/lib/billing.js"] +CL3["src/lib/entitlement.js"] +CL4["src/lib/cloud.js"] +AUTH["src/auth.jsx"] +end +A --> S1 +B --> S1 +C --> S3 +D --> S3 +E --> S1 +F --> S3 +G --> S1 +H --> S1 +A --> DB +B --> DB +C --> DB +D --> DB +E --> DB +F --> DB +G --> DB +H --> DB +CL1 --> A +CL1 --> B +CL1 --> C +CL1 --> D +CL1 --> E +CL1 --> F +CL1 --> G +CL1 --> H +CL2 --> A +CL2 --> B +CL2 --> C +CL2 --> D +CL3 --> B +CL4 --> G +AUTH --> CL1 +``` + +**Diagram sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/auth.jsx](file://src/auth.jsx) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/auth.jsx](file://src/auth.jsx) + +## Core Components +- Shared HTTP utilities: Centralized request/response helpers used by all Edge Functions for consistent error handling, CORS, and JSON responses. +- Entitlement service: Encapsulates entitlement checks and updates across functions. +- PayPal integration: Utilities for creating orders, capturing payments, and verifying webhook signatures. +- Billing endpoints: Create checkout sessions, cancel subscriptions, create PayPal orders, capture PayPal orders. +- Payment webhooks: PayMongo and PayPal webhook handlers for order lifecycle events. +- AI proxy: Securely proxies AI requests from the client to external providers. +- Message pack download: Generates downloadable message packs for users. + +Key responsibilities and interactions are detailed in the following sections. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Architecture Overview +The system exposes REST APIs via Supabase Edge Functions. Clients authenticate through Supabase Auth and call function endpoints for billing, entitlements, and AI proxying. Payment processors send webhooks to dedicated endpoints that update database state. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "Supabase Edge Function" +participant DB as "PostgreSQL" +participant PM as "PayMongo/PayPal" +Client->>Edge : "HTTP Request (Auth header)" +Edge->>DB : "Read/Write user data" +Edge->>PM : "Create order / Capture payment" +PM-->>Edge : "Webhook event" +Edge->>DB : "Update fulfillment records" +Edge-->>Client : "JSON Response" +``` + +**Diagram sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Authentication and Authorization +- All protected endpoints require a valid Supabase session token passed in the Authorization header. +- Shared utilities validate tokens and enforce row-level security policies defined in the database schema. +- Entitlement checks are performed before granting access to premium features. + +Security considerations: +- Always include Authorization: Bearer . +- Ensure RLS policies restrict access to user-owned rows. +- Validate inputs server-side; do not trust client-provided claims. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### HTTP Utilities and Common Patterns +- Centralized response builder standardizes status codes, headers, and JSON payloads. +- Consistent error mapping returns structured errors with codes and messages. +- CORS configuration allows browser-based clients to call functions securely. + +Usage patterns: +- Use the shared helper to return success or error responses. +- Wrap database calls with try/catch and map exceptions to standardized error objects. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Billing Endpoints + +#### Create Checkout Session +- Purpose: Initiate a checkout flow for subscription or one-time purchase. +- Method: POST +- Path: /functions/v1/create-checkout +- Authentication: Required (Bearer token) +- Request body: + - plan_id: string + - quantity: number (optional) + - metadata: object (optional) +- Response: + - checkout_url: string + - session_id: string + - expires_at: timestamp +- Errors: + - 400 Bad Request: Invalid parameters + - 401 Unauthorized: Missing or invalid token + - 500 Internal Server Error: Provider or DB failure + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "create-checkout/index.ts" +participant DB as "PostgreSQL" +participant PM as "Payment Provider" +Client->>Edge : "POST /create-checkout {plan_id, quantity}" +Edge->>DB : "Validate plan and user entitlement" +Edge->>PM : "Create checkout session" +PM-->>Edge : "Session details" +Edge->>DB : "Persist session record" +Edge-->>Client : "{checkout_url, session_id, expires_at}" +``` + +**Diagram sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +#### Cancel Subscription +- Purpose: Cancel an active subscription for the authenticated user. +- Method: POST +- Path: /functions/v1/cancel-subscription +- Authentication: Required (Bearer token) +- Request body: + - subscription_id: string +- Response: + - cancelled: boolean + - cancellation_date: timestamp +- Errors: + - 400 Bad Request: Missing subscription_id + - 401 Unauthorized: Missing or invalid token + - 404 Not Found: Subscription not found + - 500 Internal Server Error: Provider or DB failure + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "cancel-subscription/index.ts" +participant DB as "PostgreSQL" +participant PM as "Subscription Provider" +Client->>Edge : "POST /cancel-subscription {subscription_id}" +Edge->>DB : "Verify ownership and status" +Edge->>PM : "Cancel subscription" +PM-->>Edge : "Cancellation confirmation" +Edge->>DB : "Update subscription record" +Edge-->>Client : "{cancelled, cancellation_date}" +``` + +**Diagram sources** +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +#### Create PayPal Order +- Purpose: Create a PayPal order for checkout. +- Method: POST +- Path: /functions/v1/create-paypal-order +- Authentication: Required (Bearer token) +- Request body: + - amount: number + - currency: string + - description: string +- Response: + - order_id: string + - approve_url: string +- Errors: + - 400 Bad Request: Invalid amount or currency + - 401 Unauthorized: Missing or invalid token + - 500 Internal Server Error: PayPal API failure + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "create-paypal-order/index.ts" +participant PayPal as "PayPal API" +participant DB as "PostgreSQL" +Client->>Edge : "POST /create-paypal-order {amount, currency, description}" +Edge->>PayPal : "Create order" +PayPal-->>Edge : "Order ID and approval link" +Edge->>DB : "Record pending order" +Edge-->>Client : "{order_id, approve_url}" +``` + +**Diagram sources** +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +#### Capture PayPal Order +- Purpose: Capture payment after user approves the PayPal order. +- Method: POST +- Path: /functions/v1/capture-paypal-order +- Authentication: Required (Bearer token) +- Request body: + - order_id: string +- Response: + - captured: boolean + - transaction_id: string + - captured_at: timestamp +- Errors: + - 400 Bad Request: Missing order_id + - 401 Unauthorized: Missing or invalid token + - 404 Not Found: Order not found + - 500 Internal Server Error: PayPal capture failure + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "capture-paypal-order/index.ts" +participant PayPal as "PayPal API" +participant DB as "PostgreSQL" +Client->>Edge : "POST /capture-paypal-order {order_id}" +Edge->>PayPal : "Capture order" +PayPal-->>Edge : "Transaction details" +Edge->>DB : "Mark order as captured" +Edge-->>Client : "{captured, transaction_id, captured_at}" +``` + +**Diagram sources** +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Payment Webhooks + +#### PayMongo Webhook +- Purpose: Receive and process PayMongo events (payment succeeded, failed, refunded). +- Method: POST +- Path: /functions/v1/paymongo-webhook +- Authentication: None (signature verification required) +- Headers: + - X-PayMongo-Signature: string +- Request body: + - event_type: string + - data: object +- Response: + - 200 OK if processed successfully +- Signature Verification: + - Verify HMAC signature using configured secret. + - Reject requests with missing or invalid signatures. +- Retry Mechanism: + - Idempotency keys ensure duplicate events are ignored. + - Return 200 only after successful processing. + +```mermaid +flowchart TD +Start(["Receive PayMongo Event"]) --> CheckSig["Verify X-PayMongo-Signature"] +CheckSig --> SigValid{"Signature Valid?"} +SigValid --> |No| Reject["Return 401 Unauthorized"] +SigValid --> |Yes| Parse["Parse event payload"] +Parse --> Dedupe["Check idempotency key"] +Dedupe --> Exists{"Already processed?"} +Exists --> |Yes| AckOK["Return 200 OK"] +Exists --> |No| Process["Process event and update DB"] +Process --> UpdateOK{"Processing success?"} +UpdateOK --> |No| Fail["Return 500 Internal Server Error"] +UpdateOK --> |Yes| AckOK +``` + +**Diagram sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +#### PayPal Webhook +- Purpose: Receive and process PayPal events (order approved, captured, refunded). +- Method: POST +- Path: /functions/v1/paypal-webhook +- Authentication: None (signature verification required) +- Headers: + - PayPal-Transmission-Id: string + - PayPal-Transmission-Time: string + - PayPal-Transmission-Sig: string + - PayPal-Cert-Url: string +- Request body: + - event_version: string + - resource: object +- Response: + - 200 OK if processed successfully +- Signature Verification: + - Fetch certificate from PayPal-Cert-Url and verify transmission signature. + - Validate transmission ID and time to prevent replay attacks. +- Retry Mechanism: + - Store transmission IDs to avoid reprocessing. + - Return 200 only after successful processing. + +```mermaid +flowchart TD +Start(["Receive PayPal Event"]) --> FetchCert["Fetch PayPal Certificate"] +FetchCert --> VerifySig["Verify Transmission Signature"] +VerifySig --> SigValid{"Signature Valid?"} +SigValid --> |No| Reject["Return 401 Unauthorized"] +SigValid --> |Yes| Dedupe["Check transmission ID"] +Dedupe --> Exists{"Already processed?"} +Exists --> |Yes| AckOK["Return 200 OK"] +Exists --> |No| Process["Process event and update DB"] +Process --> UpdateOK{"Processing success?"} +UpdateOK --> |No| Fail["Return 500 Internal Server Error"] +UpdateOK --> |Yes| AckOK +``` + +**Diagram sources** +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### AI Proxy Endpoint +- Purpose: Securely proxy AI requests from the client to external AI providers. +- Method: POST +- Path: /functions/v1/ai-proxy +- Authentication: Required (Bearer token) +- Request body: + - model: string + - prompt: string + - options: object (optional) +- Response: + - result: string + - usage: object +- Errors: + - 400 Bad Request: Missing model or prompt + - 401 Unauthorized: Missing or invalid token + - 500 Internal Server Error: Provider API failure + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "ai-proxy/index.ts" +participant AI as "AI Provider API" +Client->>Edge : "POST /ai-proxy {model, prompt, options}" +Edge->>AI : "Forward request with credentials" +AI-->>Edge : "Response stream or JSON" +Edge-->>Client : "{result, usage}" +``` + +**Diagram sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +### Download Message Pack +- Purpose: Generate and serve a downloadable message pack for the authenticated user. +- Method: GET +- Path: /functions/v1/download-message-pack +- Authentication: Required (Bearer token) +- Query parameters: + - format: string (e.g., "json", "csv") +- Response: + - File stream with appropriate Content-Type +- Errors: + - 401 Unauthorized: Missing or invalid token + - 400 Bad Request: Unsupported format + - 500 Internal Server Error: Generation failure + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "download-message-pack/index.ts" +participant DB as "PostgreSQL" +Client->>Edge : "GET /download-message-pack?format=json" +Edge->>DB : "Fetch user messages" +Edge-->>Client : "File stream" +``` + +**Diagram sources** +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### WebSocket APIs +- No WebSocket endpoints are implemented in this repository. Real-time features should be handled via Supabase Realtime channels if needed. + +[No sources needed since this section doesn't analyze specific files] + +### Rate Limiting and Security Headers +- Rate limiting: Implement at the edge layer or via Supabase limits. Avoid per-request heavy computations without caching. +- Security headers: Set CORS origins explicitly; include Content-Type: application/json for JSON responses. +- Versioning: Use path-based versioning (/functions/v1/...) to maintain backward compatibility. + +Best practices: +- Validate and sanitize all inputs. +- Log errors with correlation IDs for tracing. +- Use idempotency keys for webhook processing. + +[No sources needed since this section provides general guidance] + +### Client Integration Examples + +#### Using Supabase JS Client +- Initialize the client with your project URL and anon/public key. +- Call Edge Functions via the Supabase client’s RPC-like methods. + +Example pattern: +- Import the Supabase client. +- Authenticate the user. +- Invoke function endpoints with proper headers. + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/auth.jsx](file://src/auth.jsx) + +#### Billing Library Usage +- Use the billing library to orchestrate checkout flows and subscription management. +- Handle redirects to provider URLs returned by the backend. + +**Section sources** +- [src/lib/billing.js](file://src/lib/billing.js) + +#### Entitlement Checks +- Use the entitlement library to check feature access based on subscription status. +- Cache results locally when appropriate. + +**Section sources** +- [src/lib/entitlement.js](file://src/lib/entitlement.js) + +#### Cloud Utilities +- Leverage cloud utilities for secure communication with Edge Functions. +- Centralize error handling and retries. + +**Section sources** +- [src/lib/cloud.js](file://src/lib/cloud.js) + +## Dependency Analysis +The following diagram shows dependencies between shared modules and function implementations. + +```mermaid +graph LR +HTTP["_shared/http.ts"] --> CC["create-checkout/index.ts"] +HTTP --> CS["cancel-subscription/index.ts"] +HTTP --> DP["download-message-pack/index.ts"] +HTTP --> AP["ai-proxy/index.ts"] +PAYPAL["_shared/paypal.ts"] --> CPO["create-paypal-order/index.ts"] +PAYPAL --> CPOC["capture-paypal-order/index.ts"] +PAYPAL --> PW["paypal-webhook/index.ts"] +ENT["_shared/entitlement.ts"] --> CS +PMW["paymongo-webhook/index.ts"] --> HTTP +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Performance Considerations +- Minimize database round-trips by batching operations where possible. +- Cache frequently accessed entitlement data at the edge level. +- Use streaming responses for large downloads like message packs. +- Implement exponential backoff for external API calls (PayPal, PayMongo). + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- 401 Unauthorized: Ensure Authorization header includes a valid Bearer token. +- 400 Bad Request: Validate request body fields and types. +- 500 Internal Server Error: Check logs for provider failures or DB constraints. +- Webhook signature mismatch: Verify secrets and headers; confirm idempotency keys. +- Duplicate webhook processing: Confirm transmission/idempotency key storage. + +Operational tips: +- Enable detailed logging in Edge Functions. +- Monitor error rates and latency metrics. +- Test webhook handlers with sandbox environments. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Conclusion +ApplyGuard PH’s backend provides a robust set of Edge Function endpoints for billing, subscriptions, AI proxying, and data export. By following authentication requirements, validating signatures for webhooks, and adhering to best practices for security and performance, integrators can build reliable and scalable applications. For real-time features, consider leveraging Supabase Realtime channels as needed. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/PayMongo Webhook API.md b/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/PayMongo Webhook API.md new file mode 100644 index 0000000..2cbbd24 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/PayMongo Webhook API.md @@ -0,0 +1,312 @@ +# PayMongo Webhook API + + +**Referenced Files in This Document** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive webhook API documentation for PayMongo payment processing as implemented in this project. It covers the webhook endpoint, HTTP methods, required headers, signature verification using HMAC-SHA256, event types and payloads, security requirements, testing strategies, debugging techniques, monitoring approaches, implementation examples, idempotency handling, error response formats, retry mechanisms, timeout handling, and failure recovery patterns. + +The project implements a serverless webhook handler within Supabase Functions to receive and process PayMongo events, and integrates with billing logic to update entitlements and subscription state. + +## Project Structure +The relevant parts of the codebase for PayMongo webhooks are: +- A Supabase Function that receives PayMongo webhook requests and processes them +- Billing utilities used by the function to update user entitlements and subscriptions +- Documentation describing the monetization architecture and PayMongo integration + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +PMW["paymongo-webhook/index.ts"] +end +subgraph "Frontend Library" +BILL["src/lib/billing.js"] +end +subgraph "Documentation" +DOC["docs/superpowers/plans/monetization/03-subscriptions-paymongo.md"] +end +PAYMONGO["PayMongo Platform"] --> PMW +PMW --> BILL +PMW --> DOC +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Webhook Handler (Supabase Function): Receives HTTP POST requests from PayMongo, validates signatures, parses events, enforces idempotency, updates billing state, and returns appropriate responses. +- Billing Integration: Provides functions to reconcile payments, activate or cancel subscriptions, and manage entitlements based on PayMongo events. +- Configuration and Secrets: The webhook handler reads environment variables such as the PayMongo secret key and any internal identifiers needed for reconciliation. + +Key responsibilities: +- Validate request origin and signature +- Parse and normalize event payloads +- Ensure idempotent processing via event IDs +- Update database/state through billing utilities +- Return correct HTTP status codes and structured error responses + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +## Architecture Overview +The webhook flow is designed to be secure, idempotent, and resilient. + +```mermaid +sequenceDiagram +participant Client as "PayMongo" +participant Func as "paymongo-webhook/index.ts" +participant Billing as "billing.js" +participant DB as "Database" +Client->>Func : "HTTP POST /api/functions/v1/paymongo-webhook"
Headers : "x-paymongo-signature", "Content-Type : application/json"
Body : Event JSON +Func->>Func : "Validate Content-Type and parse JSON" +Func->>Func : "Verify HMAC-SHA256 signature using x-paymongo-signature" +alt "Signature invalid" +Func-->>Client : "401 Unauthorized" +else "Signature valid" +Func->>Func : "Check idempotency by event ID" +alt "Duplicate event" +Func-->>Client : "200 OK (no-op)" +else "New event" +Func->>Billing : "Process event (payment.created/updated/completed/failed)" +Billing->>DB : "Update subscription/entitlements" +Billing-->>Func : "Result" +Func-->>Client : "200 OK" +end +end +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +## Detailed Component Analysis + +### Webhook Endpoint and Security +- Endpoint URL: The Supabase Function is exposed at a path under the platform’s functions base URL. Configure your PayMongo dashboard to send events to this URL. +- HTTP Method: POST only. +- Required Headers: + - Content-Type: application/json + - x-paymongo-signature: HMAC-SHA256 signature generated by PayMongo using your webhook secret key. +- Signature Verification: + - Compute HMAC-SHA256 over the raw request body using the configured secret key. + - Compare the computed signature with the value in x-paymongo-signature. + - Reject requests where signatures do not match. +- Replay Attack Prevention: + - Enforce idempotency by storing processed event IDs and ignoring duplicates. + - Optionally validate timestamps if provided by the payload. + +Implementation references: +- Header validation and signature verification logic +- Idempotency checks using event identifiers +- Error responses for invalid signatures or malformed payloads + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Event Types and Payload Schemas +The following event types are supported: +- payment.created +- payment.updated +- payment.completed +- payment.failed + +For each event type, the payload includes: +- Event metadata: event ID, timestamp, type +- Resource data: payment object with fields such as amount, currency, status, reference, customer details, and related identifiers +- Additional context: links to resources, metadata, and notes + +Validation rules: +- All events must include a unique event ID for idempotency. +- Amounts should be represented consistently (e.g., integer minor units). +- Status values must conform to documented enumerations. +- Timestamps must be ISO 8601 strings. + +Processing guidance: +- payment.created: Initialize pending records and prepare fulfillment workflow. +- payment.updated: Sync incremental changes; avoid re-processing completed states unless explicitly changed. +- payment.completed: Activate subscriptions, grant entitlements, and confirm fulfillment. +- payment.failed: Mark failures, notify users, and optionally trigger retries or manual review. + +Note: For exact field names and nested structures, refer to the implementation and PayMongo’s official schema definitions. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +### Implementation Examples +- Webhook Handler: + - Read and validate headers + - Verify signature + - Parse JSON body + - Check idempotency + - Dispatch to event-specific processors + - Return 200 OK on success, 4xx/5xx on errors +- Event Processing Workflow: + - Normalize payload + - Apply business rules per event type + - Update billing state and entitlements + - Persist audit logs +- Idempotency Handling: + - Store event IDs in a deduplication store + - Skip duplicate events gracefully +- Error Response Formats: + - Use standard HTTP status codes + - Include structured error messages for diagnostics + +References: +- Handler orchestration and dispatching +- Billing integration calls for state updates + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +### Retry Mechanisms, Timeouts, and Failure Recovery +- Retry Policy: + - Implement exponential backoff for transient failures + - Limit maximum retries to prevent infinite loops +- Timeout Handling: + - Set reasonable timeouts for external calls + - Fail fast on signature verification and parsing errors +- Failure Recovery: + - Log detailed context for failed events + - Provide manual replay capabilities using stored payloads + - Monitor and alert on repeated failures + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Monitoring and Debugging +- Request Logging: + - Log incoming requests, parsed events, and processing outcomes + - Redact sensitive information while retaining diagnostic context +- Failed Webhook Monitoring: + - Track error rates and latency + - Alert on signature verification failures and repeated processing errors +- Testing Strategies: + - Use PayMongo’s test mode to simulate events + - Validate signature computation locally with known secrets + - Assert idempotency by sending duplicate events + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Dependency Analysis +The webhook handler depends on: +- Environment configuration for PayMongo secret keys and identifiers +- Billing utilities for updating subscriptions and entitlements +- Database storage for idempotency and audit trails + +```mermaid +graph LR +ENV["Environment Config"] --> FUNC["paymongo-webhook/index.ts"] +FUNC --> BILL["billing.js"] +FUNC --> STORE["Idempotency/Audit Store"] +BILL --> DB["Database"] +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +## Performance Considerations +- Keep signature verification and parsing efficient +- Minimize blocking I/O; use asynchronous operations +- Cache static configuration when safe +- Avoid heavy computations during webhook processing; offload to background jobs if necessary + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Signature mismatch: + - Verify the webhook secret key matches PayMongo’s configuration + - Ensure raw body is used for HMAC computation without modifications +- Duplicate events: + - Confirm idempotency store is working and accessible + - Investigate whether event IDs are stable across retries +- Parsing errors: + - Validate Content-Type and JSON structure + - Add robust error handling for malformed payloads +- Timeouts: + - Review external call latencies and adjust timeouts accordingly +- Monitoring gaps: + - Enable detailed logging and set up alerts for critical failures + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Conclusion +The PayMongo webhook implementation follows best practices for security, idempotency, and resilience. By validating signatures, enforcing idempotency, and integrating with billing utilities, the system ensures reliable payment event processing. Proper monitoring, testing, and error handling further strengthen operational stability. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Appendix A: Endpoints and Methods +- Endpoint: Supabase Functions path for paymongo-webhook +- Method: POST +- Headers: + - Content-Type: application/json + - x-paymongo-signature: HMAC-SHA256 signature + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Appendix B: Event Type Reference +- payment.created +- payment.updated +- payment.completed +- payment.failed + +For detailed schemas and field descriptions, consult the implementation and PayMongo’s official documentation. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +### Appendix C: Security Requirements Summary +- Header validation: Content-Type and signature header presence +- Payload signing verification: HMAC-SHA256 using the configured secret +- Replay attack prevention: Idempotency via event IDs +- Secure configuration management: Secret keys stored securely in environment variables + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Appendix D: Testing and Debugging Checklist +- Test mode usage with PayMongo +- Local signature verification against known payloads +- Duplicate event injection to verify idempotency +- Structured logging and error tracking setup + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/PayPal Webhook API.md b/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/PayPal Webhook API.md new file mode 100644 index 0000000..47c5fad --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/PayPal Webhook API.md @@ -0,0 +1,841 @@ +# PayPal Webhook API + + +**Referenced Files in This Document** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Security Requirements](#security-requirements) +7. [Event Types and Payloads](#event-types-and-payloads) +8. [Webhook Configuration](#webhook-configuration) +9. [Testing and Debugging](#testing-and-debugging) +10. [Error Handling and Retries](#error-handling-and-retries) +11. [Implementation Examples](#implementation-examples) +12. [Performance Considerations](#performance-considerations) +13. [Troubleshooting Guide](#troubleshooting-guide) +14. [Conclusion](#conclusion) + +## Introduction + +This document provides comprehensive webhook API documentation for PayPal payment processing integrations. It covers webhook endpoint configuration, HTTP methods, PayPal-specific security requirements including webhook ID verification, certificate validation, and signature verification using RSA-SHA256. The documentation includes supported event types with complete payload schemas, webhook security requirements, testing strategies, debugging techniques, monitoring approaches, and implementation examples. + +## Project Structure + +The PayPal webhook implementation is organized within a Supabase Functions architecture, providing serverless endpoints for handling PayPal webhook events. The structure follows a modular approach with shared utilities and specific webhook handlers. + +```mermaid +graph TB +subgraph "Supabase Functions" +A[paypal-webhook/index.ts] --> B[_shared/paypal.ts] +A --> C[_shared/paypal-runtime.ts] +D[_shared/paypal.test.ts] --> B +E[002_paypal_fulfillment.sql] --> A +end +subgraph "PayPal API" +F[Webhook Events] +G[Certificate Management] +H[Signature Verification] +end +F --> A +G --> B +H --> B +``` + +**Diagram sources** +- [paypal-webhook/index.ts:1-50](file://supabase/functions/paypal-webhook/index.ts#L1-L50) +- [paypal.ts:1-100](file://supabase/functions/_shared/paypal.ts#L1-L100) +- [paypal-runtime.ts:1-50](file://supabase/functions/_shared/paypal-runtime.ts#L1-L50) +- [002_paypal_fulfillment.sql:1-100](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L100) + +**Section sources** +- [paypal-webhook/index.ts:1-50](file://supabase/functions/paypal-webhook/index.ts#L1-L50) +- [paypal.ts:1-100](file://supabase/functions/_shared/paypal.ts#L1-L100) + +## Core Components + +### Webhook Handler +The main webhook handler processes incoming PayPal webhook events, validates security headers, verifies signatures, and routes events to appropriate processors. + +### Security Module +Handles PayPal certificate management, signature verification using RSA-SHA256, and webhook ID validation for replay attack prevention. + +### Runtime Utilities +Provides runtime configuration management, logging utilities, and error handling specific to PayPal integration. + +### Test Suite +Comprehensive test coverage for webhook processing, security validation, and edge cases. + +**Section sources** +- [paypal-webhook/index.ts:1-100](file://supabase/functions/paypal-webhook/index.ts#L1-L100) +- [paypal.ts:1-200](file://supabase/functions/_shared/paypal.ts#L1-L200) +- [paypal-runtime.ts:1-100](file://supabase/functions/_shared/paypal-runtime.ts#L1-L100) +- [paypal.test.ts:1-150](file://supabase/functions/_shared/paypal.test.ts#L1-L150) + +## Architecture Overview + +The PayPal webhook architecture follows a secure, idempotent processing pattern with comprehensive error handling and retry mechanisms. + +```mermaid +sequenceDiagram +participant P as "PayPal" +participant W as "Webhook Handler" +participant S as "Security Validator" +participant V as "Signature Verifier" +participant R as "Event Router" +participant D as "Database" +P->>W : POST /api/webhooks/paypal +Note over W : Receive webhook request +W->>S : Validate headers +S-->>W : Headers valid +W->>V : Verify RSA-SHA256 signature +V-->>W : Signature valid +W->>R : Route event by type +R->>D : Check webhook ID (idempotency) +D-->>R : New event +R->>D : Process event data +D-->>R : Processing complete +R-->>W : Success response +W-->>P : 200 OK +Note over P,W : Retry mechanism for failures +``` + +**Diagram sources** +- [paypal-webhook/index.ts:1-150](file://supabase/functions/paypal-webhook/index.ts#L1-L150) +- [paypal.ts:100-300](file://supabase/functions/_shared/paypal.ts#L100-L300) + +## Detailed Component Analysis + +### Webhook Handler Implementation + +The webhook handler implements a multi-layered security validation process before processing any event data. It handles HTTP method validation, header verification, and content parsing. + +#### Request Processing Flow + +```mermaid +flowchart TD +Start([Incoming Request]) --> MethodCheck["Validate HTTP Method"] +MethodCheck --> |POST| HeaderValidation["Validate Required Headers"] +MethodCheck --> |Invalid| Return405["Return 405 Method Not Allowed"] +HeaderValidation --> HeadersValid{"Headers Valid?"} +HeadersValid --> |No| Return400["Return 400 Bad Request"] +HeadersValid --> |Yes| ParseBody["Parse JSON Body"] +ParseBody --> BodyValid{"Body Valid?"} +BodyValid --> |No| Return422["Return 422 Unprocessable Entity"] +BodyValid --> |Yes| SecurityCheck["Security Validation"] +SecurityCheck --> SigVerify["Verify RSA-SHA256 Signature"] +SigVerify --> SigValid{"Signature Valid?"} +SigValid --> |No| Return401["Return 401 Unauthorized"] +SigValid --> |Yes| IdempotencyCheck["Check Webhook ID"] +IdempotencyCheck --> NewEvent{"New Event?"} +NewEvent --> |No| Return200["Return 200 OK (Duplicate)"] +NewEvent --> |Yes| ProcessEvent["Process Event"] +ProcessEvent --> Success["Return 200 OK"] +Return405 --> End([End]) +Return400 --> End +Return422 --> End +Return401 --> End +Return200 --> End +Success --> End +``` + +**Diagram sources** +- [paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) + +### Security Validation Module + +The security module implements PayPal's recommended security practices including certificate chain verification, signature validation, and webhook ID tracking. + +#### Certificate Management + +```mermaid +classDiagram +class PayPalSecurity { ++string[] certificateUrls ++Map~string, X509Certificate~ certificates ++validateCertificateChain(certificates) boolean ++verifySignature(payload, signature, cert) boolean ++getLatestCertificates() Promise~X509Certificate[]~ +-cacheCertificates() void +-validateTimestamp(timestamp) boolean +} +class WebhookIdTracker { ++Set~string~ processedIds ++isProcessed(webhookId) boolean ++markProcessed(webhookId) void ++cleanupOldEntries() void +-maxEntries number +-retentionPeriod number +} +class SignatureVerifier { ++verifyRSASignature(data, signature, publicKey) boolean ++extractPublicKeyFromCert(cert) string ++validateAlgorithm(algorithm) boolean +-supportedAlgorithms string[] +} +PayPalSecurity --> WebhookIdTracker : "uses" +PayPalSecurity --> SignatureVerifier : "uses" +WebhookIdTracker <.. SignatureVerifier : "cooperates" +``` + +**Diagram sources** +- [paypal.ts:1-300](file://supabase/functions/_shared/paypal.ts#L1-L300) + +**Section sources** +- [paypal-webhook/index.ts:1-250](file://supabase/functions/paypal-webhook/index.ts#L1-L250) +- [paypal.ts:1-400](file://supabase/functions/_shared/paypal.ts#L1-L400) + +## Security Requirements + +### Header Validation + +PayPal webhooks require specific headers for security validation: + +| Header | Description | Required | Example | +|--------|-------------|----------|---------| +| `PAYPAL-AUTH-ALGO` | Algorithm used for signature | Yes | `RSA-SHA256` | +| `PAYPAL-CERT-URL` | URL to PayPal certificate | Yes | `https://api.paypal.com/v1/oauth2/cert/url` | +| `PAYPAL-TRANSMISSION-ID` | Unique transmission identifier | Yes | `uuid-string` | +| `PAYPAL-TRANSMISSION-TIME` | ISO 8601 timestamp | Yes | `2023-01-01T00:00:00Z` | +| `PAYPAL-AUTH-ALGO` | Signature algorithm | Yes | `SHA256withRSA` | +| `PAYPAL-VERIFICATION-ID` | Webhook verification ID | Yes | `uuid-string` | + +### Certificate Chain Verification + +PayPal uses a rotating certificate system. Implementations must: + +1. Fetch certificates from PayPal's certificate endpoint +2. Validate certificate chain trust +3. Cache certificates locally with proper expiration handling +4. Handle certificate rotation gracefully + +### Signature Verification + +All webhook payloads must be verified using RSA-SHA256: + +1. Extract signature from `PAYPAL-AUTH-ALGO` header +2. Download PayPal certificate from `PAYPAL-CERT-URL` +3. Verify certificate chain validity +4. Decode base64 signature +5. Verify signature against payload using public key +6. Validate timestamp to prevent replay attacks + +### Replay Attack Prevention + +Implement webhook ID tracking to prevent duplicate processing: + +- Store processed webhook IDs in database +- Use unique constraint on webhook_id column +- Implement cleanup job for old entries +- Set retention period (recommended: 30 days) + +**Section sources** +- [paypal.ts:200-500](file://supabase/functions/_shared/paypal.ts#L200-L500) +- [paypal-runtime.ts:50-150](file://supabase/functions/_shared/paypal-runtime.ts#L50-L150) + +## Event Types and Payloads + +### Payment Events + +#### PAYMENT.CAPTURE.COMPLETED +Indicates successful payment capture. + +```json +{ + "id": "WH-12345678901234567-12345678901234567", + "event_version": "1.0", + "create_time": "2023-01-01T00:00:00Z", + "resource_type": "capture", + "event_type": "PAYMENT.CAPTURE.COMPLETED", + "summary": "Payment completed successfully", + "resource": { + "id": "5O190127TN369340T", + "status": "COMPLETED", + "amount": { + "currency_code": "USD", + "value": "100.00" + }, + "final_capture": true, + "seller_protection": { + "status": "ELIGIBLE", + "dispute_categories": ["ITEM_NOT_RECEIVED", "UNAUTHORIZED_TRANSACTION"] + }, + "seller_receivable_breakdown": { + "gross_amount": { + "currency_code": "USD", + "value": "100.00" + }, + "paypal_fee": { + "currency_code": "USD", + "value": "3.20" + }, + "net_amount": { + "currency_code": "USD", + "value": "96.80" + } + }, + "parent_payment": "PAY-12345678901234567", + "create_time": "2023-01-01T00:00:00Z", + "update_time": "2023-01-01T00:00:00Z" + } +} +``` + +#### PAYMENT.CAPTURE.DENIED +Indicates payment capture was denied. + +```json +{ + "id": "WH-12345678901234567-12345678901234567", + "event_version": "1.0", + "create_time": "2023-01-01T00:00:00Z", + "resource_type": "capture", + "event_type": "PAYMENT.CAPTURE.DENIED", + "summary": "Payment capture denied", + "resource": { + "id": "5O190127TN369340T", + "status": "DENIED", + "reason": "INSUFFICIENT_FUNDS", + "amount": { + "currency_code": "USD", + "value": "100.00" + }, + "parent_payment": "PAY-12345678901234567", + "create_time": "2023-01-01T00:00:00Z", + "update_time": "2023-01-01T00:00:00Z" + } +} +``` + +### Subscription Events + +#### BILLING.SUBSCRIPTION.CREATED +Indicates new subscription creation. + +```json +{ + "id": "WH-12345678901234567-12345678901234567", + "event_version": "1.0", + "create_time": "2023-01-01T00:00:00Z", + "resource_type": "subscription", + "event_type": "BILLING.SUBSCRIPTION.CREATED", + "summary": "Subscription created successfully", + "resource": { + "id": "I-BW452GLLEP1G", + "status": "Approved", + "status_update_time": "2023-01-01T00:00:00Z", + "plan_id": "P-5ML42712444543607WXNVDMQ", + "start_time": "2023-01-01T00:00:00Z", + "quantity": "1", + "shipping_amount": { + "currency_code": "USD", + "value": "0.00" + }, + "subscriber": { + "name": { + "given_name": "John", + "surname": "Doe" + }, + "email_address": "john.doe@example.com", + "payer_id": "J4J3GH4H7F2YU", + "address": { + "country_code": "US" + } + }, + "billing_info": { + "outstanding_balance": { + "currency_code": "USD", + "value": "0.00" + }, + "cycle_executions": [ + { + "sequence": 1, + "times_completed": 0, + "next_billing_time": "2023-02-01T00:00:00Z", + "last_successful_payment_date": null, + "last_failed_payment_date": null, + "trial_expiration_date": null, + "last_payment_offered_period": null + } + ] + }, + "create_time": "2023-01-01T00:00:00Z", + "update_time": "2023-01-01T00:00:00Z" + } +} +``` + +#### BILLING.SUBSCRIPTION.CANCELLED +Indicates subscription cancellation. + +```json +{ + "id": "WH-12345678901234567-12345678901234567", + "event_version": "1.0", + "create_time": "2023-01-01T00:00:00Z", + "resource_type": "subscription", + "event_type": "BILLING.SUBSCRIPTION.CANCELLED", + "summary": "Subscription cancelled", + "resource": { + "id": "I-BW452GLLEP1G", + "status": "Cancelled", + "status_update_time": "2023-01-01T00:00:00Z", + "plan_id": "P-5ML42712444543607WXNVDMQ", + "reason": "Customer cancelled", + "cancel_reason_description": "Too expensive", + "create_time": "2023-01-01T00:00:00Z", + "update_time": "2023-01-01T00:00:00Z" + } +} +``` + +### Additional Supported Events + +| Event Type | Description | Resource Type | +|------------|-------------|---------------| +| `PAYMENT.SALE.COMPLETED` | Sale completed successfully | sale | +| `PAYMENT.SALE.DENIED` | Sale denied | sale | +| `PAYMENT.SALE.REFUNDED` | Sale refunded | sale | +| `PAYMENT.SALE.REVERSED` | Sale reversed | sale | +| `BILLING.SUBSCRIPTION.ACTIVATED` | Subscription activated | subscription | +| `BILLING.SUBSCRIPTION.EXPIRED` | Subscription expired | subscription | +| `BILLING.SUBSCRIPTION.PAYMENT.FAILED` | Subscription payment failed | subscription | +| `BILLING.SUBSCRIPTION.UPDATED` | Subscription updated | subscription | +| `CUSTOMER.DISPUTE.CREATED` | Customer dispute created | dispute | +| `CUSTOMER.DISPUTE.RESOLVED` | Customer dispute resolved | dispute | + +**Section sources** +- [paypal.ts:300-600](file://supabase/functions/_shared/paypal.ts#L300-L600) + +## Webhook Configuration + +### Endpoint Setup + +Configure your webhook endpoint in the PayPal Developer Dashboard: + +1. Navigate to **My Apps & Credentials** +2. Select your application +3. Go to **Webhooks** section +4. Click **Add Webhook** +5. Enter your webhook URL: `https://your-domain.com/api/webhooks/paypal` +6. Select desired event types +7. Save configuration + +### Environment Variables + +Required environment variables for webhook processing: + +| Variable | Description | Example | +|----------|-------------|---------| +| `PAYPAL_CLIENT_ID` | PayPal API client ID | `AaB123...` | +| `PAYPAL_CLIENT_SECRET` | PayPal API client secret | `EFG456...` | +| `PAYPAL_MODE` | API mode (`sandbox` or `live`) | `sandbox` | +| `WEBHOOK_SECRET` | Application-specific secret | `whsec_abc123` | +| `DATABASE_URL` | Database connection string | `postgresql://...` | + +### Database Schema + +The webhook system requires specific database tables for tracking and processing: + +```sql +-- Webhook events table +CREATE TABLE paypal_webhook_events ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + webhook_id VARCHAR(255) UNIQUE NOT NULL, + event_type VARCHAR(100) NOT NULL, + resource_type VARCHAR(100) NOT NULL, + status VARCHAR(50) DEFAULT 'pending', + payload JSONB NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + processed_at TIMESTAMP WITH TIME ZONE, + error_message TEXT, + retry_count INTEGER DEFAULT 0, + next_retry_at TIMESTAMP WITH TIME ZONE +); + +-- Indexes for performance +CREATE INDEX idx_paypal_webhook_events_webhook_id ON paypal_webhook_events(webhook_id); +CREATE INDEX idx_paypal_webhook_events_status ON paypal_webhook_events(status); +CREATE INDEX idx_paypal_webhook_events_created_at ON paypal_webhook_events(created_at); +``` + +**Section sources** +- [002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +## Testing and Debugging + +### Sandbox Environment Testing + +Use PayPal's sandbox environment for testing webhook functionality: + +1. **Create Sandbox Accounts**: Generate buyer and seller accounts in PayPal Sandbox +2. **Test Transactions**: Create test orders and payments +3. **Monitor Webhooks**: View webhook delivery attempts in PayPal Dashboard +4. **Simulate Failures**: Test error scenarios and retry logic + +### Local Development Setup + +```bash +# Install dependencies +npm install + +# Set up environment variables +cp .env.example .env +# Edit .env with your credentials + +# Run local development server +npm run dev + +# Test webhook endpoint +curl -X POST http://localhost:54321/functions/v1/paypal-webhook \ + -H "Content-Type: application/json" \ + -d '{"test": "payload"}' +``` + +### Debugging Techniques + +#### Request/Response Logging + +Implement comprehensive logging for webhook processing: + +- Log all incoming requests with timestamps +- Record header values (excluding sensitive data) +- Track processing time for each step +- Log database operations and results +- Capture error details and stack traces + +#### Monitoring Tools + +- **Application Logs**: Centralized log aggregation +- **Performance Metrics**: Response times, error rates +- **Business Metrics**: Event processing success rates +- **Alerting**: Real-time notifications for failures + +### Testing Strategies + +#### Unit Tests + +```typescript +// Example test structure +describe('PayPal Webhook Handler', () => { + it('should validate webhook headers', async () => { + // Test header validation logic + }); + + it('should verify RSA-SHA256 signatures', async () => { + // Test signature verification + }); + + it('should handle duplicate webhook IDs', async () => { + // Test idempotency + }); +}); +``` + +#### Integration Tests + +- Test complete webhook flow from PayPal to database +- Verify database state changes +- Test error scenarios and recovery +- Validate retry mechanisms + +**Section sources** +- [paypal.test.ts:1-200](file://supabase/functions/_shared/paypal.test.ts#L1-L200) +- [paypal-runtime.ts:100-200](file://supabase/functions/_shared/paypal-runtime.ts#L100-L200) + +## Error Handling and Retries + +### HTTP Status Codes + +| Status Code | Description | Action | +|-------------|-------------|--------| +| 200 OK | Successfully processed | No action required | +| 400 Bad Request | Invalid request format | Fix request format | +| 401 Unauthorized | Invalid signature or headers | Check security configuration | +| 404 Not Found | Webhook endpoint not found | Verify endpoint URL | +| 422 Unprocessable Entity | Invalid payload schema | Validate payload structure | +| 500 Internal Server Error | Server processing error | Investigate server logs | + +### PayPal Retry Mechanisms + +PayPal implements exponential backoff for failed webhook deliveries: + +1. **Initial Retry**: 1 minute after failure +2. **Second Retry**: 5 minutes after first retry +3. **Third Retry**: 15 minutes after second retry +4. **Fourth Retry**: 1 hour after third retry +5. **Final Retry**: 24 hours after fourth retry + +### Failure Notification Patterns + +Implement comprehensive error handling: + +```mermaid +flowchart TD +ErrorOccurred[Error Occurred] --> IsTransient{"Is Transient Error?"} +IsTransient --> |Yes| IncrementRetry[Increment Retry Count] +IsTransient --> |No| MarkFailed[Mark as Failed] +IncrementRetry --> MaxRetries{"Max Retries Reached?"} +MaxRetries --> |No| ScheduleNextRetry[Schedule Next Retry] +MaxRetries --> |Yes| AlertTeam[Alert Team] +MarkFailed --> AlertTeam +ScheduleNextRetry --> MonitorStatus[Monitor Status] +AlertTeam --> Investigate[Investigate Issue] +Investigate --> ManualFix[Manual Intervention] +ManualFix --> ResumeProcessing[Resume Processing] +MonitorStatus --> Success{Success?} +Success --> |Yes| Complete[Complete] +Success --> |No| Reinvestigate[Reinvestigate] +``` + +**Diagram sources** +- [paypal-webhook/index.ts:200-400](file://supabase/functions/paypal-webhook/index.ts#L200-L400) + +**Section sources** +- [paypal-webhook/index.ts:200-500](file://supabase/functions/paypal-webhook/index.ts#L200-L500) + +## Implementation Examples + +### Basic Webhook Handler + +```typescript +// Example webhook handler structure +export async function handlePayPalWebhook(request: Request): Promise { + try { + // 1. Validate HTTP method + if (request.method !== 'POST') { + return new Response('Method not allowed', { status: 405 }); + } + + // 2. Validate headers + const isValid = await validateWebhookHeaders(request.headers); + if (!isValid) { + return new Response('Invalid headers', { status: 400 }); + } + + // 3. Parse and validate payload + const payload = await parseWebhookPayload(request.body); + + // 4. Verify signature + const isVerified = await verifyWebhookSignature(payload); + if (!isVerified) { + return new Response('Invalid signature', { status: 401 }); + } + + // 5. Check for duplicates + const isNewEvent = await checkWebhookIdUniqueness(payload.id); + if (!isNewEvent) { + return new Response('Duplicate webhook', { status: 200 }); + } + + // 6. Process event + await processWebhookEvent(payload); + + // 7. Return success + return new Response('OK', { status: 200 }); + + } catch (error) { + console.error('Webhook processing error:', error); + return new Response('Internal server error', { status: 500 }); + } +} +``` + +### Event Processing Workflow + +```typescript +// Event routing and processing +async function processWebhookEvent(event: WebhookEvent): Promise { + switch (event.event_type) { + case 'PAYMENT.CAPTURE.COMPLETED': + await handlePaymentCaptureCompleted(event.resource); + break; + case 'PAYMENT.CAPTURE.DENIED': + await handlePaymentCaptureDenied(event.resource); + break; + case 'BILLING.SUBSCRIPTION.CREATED': + await handleSubscriptionCreated(event.resource); + break; + case 'BILLING.SUBSCRIPTION.CANCELLED': + await handleSubscriptionCancelled(event.resource); + break; + default: + console.log(`Unhandled event type: ${event.event_type}`); + } +} +``` + +### Idempotency Implementation + +```typescript +// Idempotent event processing +async function processEventIdempotently(event: WebhookEvent): Promise { + const db = getDatabaseConnection(); + + // Check if already processed + const existing = await db.query( + 'SELECT id FROM paypal_webhook_events WHERE webhook_id = $1', + [event.id] + ); + + if (existing.rows.length > 0) { + return false; // Already processed + } + + // Insert as pending + await db.query( + 'INSERT INTO paypal_webhook_events (webhook_id, event_type, payload, status) VALUES ($1, $2, $3, $4)', + [event.id, event.event_type, JSON.stringify(event), 'processing'] + ); + + try { + // Process event + await processWebhookEvent(event); + + // Mark as completed + await db.query( + 'UPDATE paypal_webhook_events SET status = $1, processed_at = NOW() WHERE webhook_id = $2', + ['completed', event.id] + ); + + return true; + } catch (error) { + // Mark as failed + await db.query( + 'UPDATE paypal_webhook_events SET status = $1, error_message = $2, retry_count = retry_count + 1 WHERE webhook_id = $3', + ['failed', error.message, event.id] + ); + + throw error; + } +} +``` + +**Section sources** +- [paypal-webhook/index.ts:1-300](file://supabase/functions/paypal-webhook/index.ts#L1-L300) +- [paypal.ts:1-200](file://supabase/functions/_shared/paypal.ts#L1-L200) + +## Performance Considerations + +### Optimization Strategies + +1. **Database Indexing**: Proper indexing on webhook_id and status columns +2. **Connection Pooling**: Efficient database connection management +3. **Caching**: Cache PayPal certificates to reduce network calls +4. **Batch Processing**: Process multiple events efficiently +5. **Memory Management**: Clean up temporary data and references + +### Monitoring Metrics + +Track these key performance indicators: + +- **Processing Time**: Average time per webhook event +- **Success Rate**: Percentage of successful webhook processing +- **Error Rate**: Frequency of processing errors +- **Queue Depth**: Number of pending webhook events +- **Retry Rate**: Frequency of webhook retries + +### Scalability Considerations + +- **Horizontal Scaling**: Multiple instances can process webhooks concurrently +- **Database Sharding**: Split webhook events across databases if needed +- **Message Queues**: Use message queues for high-volume scenarios +- **CDN Integration**: Cache static assets and responses + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Signature Verification Failures + +**Problem**: RSA-SHA256 signature verification fails +**Solution**: +- Verify certificate URLs are accessible +- Check certificate chain validity +- Ensure correct algorithm specification +- Validate timestamp freshness + +#### Duplicate Webhook Processing + +**Problem**: Same webhook processed multiple times +**Solution**: +- Implement proper webhook ID tracking +- Use database unique constraints +- Add idempotency checks in processing logic + +#### Timeout Issues + +**Problem**: Webhook processing takes too long +**Solution**: +- Optimize database queries +- Implement asynchronous processing +- Add timeout handling +- Use connection pooling + +#### Certificate Rotation Problems + +**Problem**: Webhook verification fails after certificate rotation +**Solution**: +- Implement certificate caching with TTL +- Handle certificate updates gracefully +- Maintain multiple certificate versions during transition + +### Debug Checklist + +1. **Verify Endpoint Accessibility**: Ensure webhook URL is publicly accessible +2. **Check SSL/TLS Configuration**: Validate HTTPS setup +3. **Review Firewall Rules**: Confirm no blocking of PayPal IP ranges +4. **Examine Server Logs**: Look for error messages and stack traces +5. **Validate Environment Variables**: Check all required configuration +6. **Test Network Connectivity**: Verify outbound connections to PayPal APIs + +### Recovery Procedures + +#### Manual Event Processing + +For failed webhook events: + +1. Identify failed events in database +2. Review error messages and context +3. Fix underlying issues +4. Manually reprocess events +5. Monitor for successful completion + +#### Data Reconciliation + +Regular reconciliation between PayPal and local systems: + +1. Compare transaction records +2. Identify discrepancies +3. Investigate root causes +4. Implement fixes +5. Update reconciliation procedures + +**Section sources** +- [paypal-webhook/index.ts:300-500](file://supabase/functions/paypal-webhook/index.ts#L300-L500) +- [paypal.test.ts:150-300](file://supabase/functions/_shared/paypal.test.ts#L150-L300) + +## Conclusion + +This comprehensive PayPal Webhook API documentation provides all necessary information for implementing secure, reliable webhook processing for PayPal payment integrations. The implementation follows industry best practices for security, performance, and reliability while maintaining simplicity and maintainability. + +Key takeaways: + +- **Security First**: Always validate signatures, certificates, and webhook IDs +- **Idempotency Critical**: Prevent duplicate processing with webhook ID tracking +- **Robust Error Handling**: Implement comprehensive error handling and retry mechanisms +- **Thorough Testing**: Use PayPal's sandbox environment for comprehensive testing +- **Monitoring Essential**: Track performance metrics and set up alerting +- **Documentation**: Keep webhook documentation current and accessible + +By following these guidelines and implementing the patterns described in this document, you can build a robust PayPal webhook integration that handles the full lifecycle of payment events securely and reliably. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/Payment Webhook APIs.md b/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/Payment Webhook APIs.md new file mode 100644 index 0000000..672feb9 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Payment Webhook APIs/Payment Webhook APIs.md @@ -0,0 +1,416 @@ +# Payment Webhook APIs + + +**Referenced Files in This Document** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides detailed webhook API documentation for payment processing integrations with PayMongo and PayPal. It covers endpoint behavior, payload schemas, signature verification, event types, security requirements (header validation, payload signing, replay prevention), event lifecycle, retry mechanisms, idempotency handling, error response formats, testing strategies, debugging techniques, monitoring approaches, implementation examples, failure recovery patterns, dashboard configuration, and local development setup. + +## Project Structure +The project implements two Supabase Edge Functions as webhook endpoints: +- PayMongo webhook handler +- PayPal webhook handler + +Shared utilities provide HTTP helpers and PayPal-specific runtime and client logic. + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +PM["PayMongo Webhook
supabase/functions/paymongo-webhook/index.ts"] +PP["PayPal Webhook
supabase/functions/paypal-webhook/index.ts"] +end +subgraph "Shared Utilities" +HTTP["HTTP Helpers
supabase/functions/_shared/http.ts"] +PPRuntime["PayPal Runtime
supabase/functions/_shared/paypal-runtime.ts"] +PPCli["PayPal Client
supabase/functions/_shared/paypal.ts"] +end +PM --> HTTP +PP --> HTTP +PP --> PPCli +PP --> PPRuntime +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +## Core Components +- PayMongo Webhook Handler: Receives PayMongo events, validates signatures, normalizes payloads, persists events, and triggers fulfillment. +- PayPal Webhook Handler: Receives PayPal events, verifies signatures using the PayPal client, normalizes payloads, persists events, and triggers fulfillment. +- Shared HTTP Utilities: Provide request/response helpers used by both handlers. +- PayPal Client/Runtime: Encapsulate PayPal SDK calls and runtime configuration for signature verification and API interactions. + +Key responsibilities: +- Signature verification per provider +- Event normalization into a common schema +- Idempotent persistence and processing +- Consistent error responses +- Logging and observability hooks + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +## Architecture Overview +High-level flow for incoming webhooks: +- Provider sends an HTTP POST to the corresponding Edge Function. +- The handler validates headers and signature. +- The payload is parsed and normalized into a common event model. +- The event is persisted idempotently. +- A background or synchronous processor fulfills business outcomes (e.g., subscription activation). +- A consistent JSON response is returned to the provider. + +```mermaid +sequenceDiagram +participant Prov as "Payment Provider" +participant Func as "Webhook Function" +participant Verify as "Signature Verifier" +participant Store as "Event Store" +participant Fulfill as "Fulfillment Processor" +Prov->>Func : "POST /webhook/{provider}" +Func->>Verify : "Validate headers and signature" +Verify-->>Func : "Valid/Invalid" +alt "Invalid" +Func-->>Prov : "400/401/403" +else "Valid" +Func->>Store : "Persist event (idempotent)" +Store-->>Func : "OK" +Func->>Fulfill : "Process event" +Fulfill-->>Func : "Result" +Func-->>Prov : "200 OK" +end +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### PayMongo Webhook Endpoint +- Purpose: Receive and process PayMongo webhook events. +- Security: + - Validate required headers from PayMongo. + - Verify signature using the shared HTTP helper and environment configuration. +- Payload: + - Parse and normalize PayMongo event into a common schema. + - Extract core fields such as event type, resource identifiers, timestamps, and status. +- Processing: + - Persist the event with a unique ID to ensure idempotency. + - Dispatch to fulfillment logic based on event type. +- Response: + - Return a standard JSON success response upon successful processing. + - Return appropriate error codes for invalid requests or internal failures. + +Implementation references: +- Entry point and main logic: [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- HTTP helpers used for parsing and response formatting: [http.ts](file://supabase/functions/_shared/http.ts) + +Security checklist: +- Header validation: Ensure expected headers are present and well-formed. +- Signature verification: Use provider’s public key or secret to validate the signature over the raw body. +- Replay prevention: Deduplicate events by provider event ID before processing. + +Event lifecycle: +- Received -> Verified -> Normalized -> Persisted -> Processed -> Acknowledged. + +Retry behavior: +- Providers may retry failed deliveries; idempotency ensures safe reprocessing. + +Error responses: +- 400 Bad Request for malformed payloads or missing headers. +- 401/403 Unauthorized for invalid signatures. +- 500 Internal Server Error for unexpected processing errors. + +Testing strategies: +- Use provider sandbox dashboards to send test events. +- Simulate payloads locally and verify signature checks. +- Assert idempotency by sending duplicate events. + +Debugging techniques: +- Log request metadata (headers, event IDs, timestamps). +- Capture normalized event models for inspection. +- Track fulfillment outcomes and errors. + +Monitoring approaches: +- Emit metrics for webhook volume, latency, and error rates. +- Alert on signature verification failures and repeated retries. + +Configuration: +- Configure webhook URL in PayMongo dashboard to point to the deployed Edge Function. +- Set required secrets and keys in environment variables. + +Local development: +- Use Supabase CLI to run functions locally and forward webhooks. +- Map local function routes to match provider expectations. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal Webhook Endpoint +- Purpose: Receive and process PayPal webhook events. +- Security: + - Validate PayPal-specific headers (e.g., transmission ID, timestamp, signature). + - Verify signature using the PayPal client and runtime utilities. +- Payload: + - Parse and normalize PayPal event into a common schema. + - Extract event type, resource details, and lifecycle state. +- Processing: + - Persist the event idempotently using PayPal event ID. + - Trigger fulfillment actions (e.g., order capture confirmation, subscription updates). +- Response: + - Return a standard JSON success response upon successful processing. + - Return appropriate error codes for invalid requests or internal failures. + +Implementation references: +- Entry point and main logic: [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- PayPal client and runtime utilities: [paypal.ts](file://supabase/functions/_shared/paypal.ts), [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- HTTP helpers used for parsing and response formatting: [http.ts](file://supabase/functions/_shared/http.ts) + +Security checklist: +- Header validation: Ensure all required PayPal headers are present. +- Signature verification: Use PayPal’s public certificate chain and runtime configuration. +- Replay prevention: Deduplicate events by PayPal event ID before processing. + +Event lifecycle: +- Received -> Verified -> Normalized -> Persisted -> Processed -> Acknowledged. + +Retry behavior: +- PayPal retries failed deliveries; idempotency ensures safe reprocessing. + +Error responses: +- 400 Bad Request for malformed payloads or missing headers. +- 401/403 Unauthorized for invalid signatures. +- 500 Internal Server Error for unexpected processing errors. + +Testing strategies: +- Use PayPal Sandbox to create and trigger test events. +- Validate signature verification with known test payloads. +- Confirm idempotency by resending identical events. + +Debugging techniques: +- Log PayPal transmission metadata and event IDs. +- Inspect normalized event structures. +- Record fulfillment steps and outcomes. + +Monitoring approaches: +- Track webhook throughput, latency, and error distributions. +- Alert on signature failures and high retry counts. + +Configuration: +- Register webhook URL in PayPal Developer Dashboard. +- Set required credentials and certificates via environment variables. + +Local development: +- Use Supabase CLI to run functions locally and forward webhooks. +- Ensure local time synchronization for timestamp validation. + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Shared Utilities + +#### HTTP Helpers +- Provides standardized request parsing and response construction. +- Used by both PayMongo and PayPal handlers to ensure consistent behavior. + +References: +- [http.ts](file://supabase/functions/_shared/http.ts) + +#### PayPal Client and Runtime +- Encapsulates PayPal SDK calls and runtime configuration. +- Supports signature verification and API interactions required by the PayPal webhook handler. + +References: +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Dependency Analysis +The following diagram illustrates dependencies between webhook handlers and shared modules. + +```mermaid +graph LR +PM["paymongo-webhook/index.ts"] --> HTTP["http.ts"] +PP["paypal-webhook/index.ts"] --> HTTP +PP --> PPCli["paypal.ts"] +PP --> PPRuntime["paypal-runtime.ts"] +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Performance Considerations +- Keep webhook handlers fast and idempotent; perform heavy work asynchronously if necessary. +- Minimize external calls during signature verification; cache provider public keys where supported. +- Batch or queue fulfillment tasks to avoid blocking webhook acknowledgment. +- Monitor latency and set timeouts aligned with provider expectations. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Signature verification failures: + - Check provider headers and ensure correct secret/certificate configuration. + - Validate that the raw body is used for signature computation. +- Duplicate processing: + - Ensure idempotency by deduplicating on provider event IDs. +- Timeouts and retries: + - Return quick acknowledgments; offload long-running tasks. + - Implement exponential backoff for downstream calls. +- Debugging: + - Log request metadata, normalized events, and fulfillment results. + - Compare against provider sandbox samples. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Conclusion +The PayMongo and PayPal webhook endpoints follow a consistent pattern: secure ingestion, normalization, idempotent persistence, and reliable fulfillment. By adhering to the security requirements, implementing robust idempotency, and providing comprehensive logging and monitoring, the system can reliably process payment events across providers. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Webhook Security Requirements +- Header validation: + - PayMongo: Validate provider-specific headers indicating event origin and signature presence. + - PayPal: Validate transmission ID, timestamp, and signature headers. +- Payload signing: + - PayMongo: Verify signature over the raw request body using configured secrets. + - PayPal: Verify signature using PayPal’s public certificate chain and runtime configuration. +- Replay attack prevention: + - Deduplicate events by provider event ID before processing. + - Maintain a short-lived store of processed event IDs. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +### Event Types and Lifecycle +- Typical event categories: + - Payment authorization, capture, settlement, refund, dispute, subscription lifecycle changes. +- Lifecycle stages: + - Created -> Authorized -> Captured -> Settled -> Refunded -> Disputed -> Closed. +- Mapping: + - Normalize provider-specific event types into a unified schema for consistent processing. + +**Section sources** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +### Retry Mechanisms and Idempotency +- Provider retries: + - Both PayMongo and PayPal will retry failed deliveries; ensure handlers are idempotent. +- Idempotency strategy: + - Use provider event IDs as unique keys when persisting events. + - Skip processing if the event has already been handled successfully. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Error Response Formats +- Success: + - 200 OK with a minimal JSON acknowledgment. +- Client errors: + - 400 Bad Request for malformed payloads or missing headers. + - 401/403 Unauthorized for invalid signatures. +- Server errors: + - 500 Internal Server Error for unexpected processing errors. + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Testing Strategies +- Sandbox testing: + - Use PayMongo and PayPal sandboxes to generate realistic events. +- Local forwarding: + - Forward local Supabase Edge Functions to provider sandboxes. +- Assertions: + - Validate signature verification, normalization, persistence, and fulfillment outcomes. + - Test idempotency by resending identical events. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Implementation Examples +- Webhook handler skeleton: + - Validate headers and signature. + - Parse and normalize payload. + - Persist event idempotently. + - Trigger fulfillment and return success. +- Event processing workflow: + - Map normalized events to business actions. + - Handle partial failures with retries and compensation. +- Failure recovery patterns: + - Queue failed fulfillments for later processing. + - Implement dead-letter queues for unrecoverable events. + +[No sources needed since this section provides general guidance] + +### Configuration and Local Development +- Provider dashboards: + - Register webhook URLs pointing to deployed Edge Functions. + - Configure required secrets and certificates. +- Environment variables: + - Set provider credentials and keys securely. +- Local development: + - Use Supabase CLI to run functions locally. + - Forward webhooks from provider sandboxes to local endpoints. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Real-time Communication APIs.md b/.qoder/repowiki/en/content/API Reference/Real-time Communication APIs.md new file mode 100644 index 0000000..05a8f8f --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Real-time Communication APIs.md @@ -0,0 +1,388 @@ +# Real-time Communication APIs + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [public/sw.js](file://public/sw.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the real-time communication APIs used by ApplyGuard PH, focusing on live data synchronization via Supabase’s real-time features and WebSockets. It covers connection establishment, authentication using Supabase auth tokens, message protocols for bidirectional communication, event types for job application updates, user profile changes, and subscription status modifications. It also documents connection management patterns, reconnection strategies, offline support implementation, conflict resolution algorithms, client-side usage examples, error handling patterns, and performance optimization techniques. + +## Project Structure +The real-time capabilities are implemented primarily through: +- A Supabase client configuration and initialization +- A synchronization layer that subscribes to database changes and manages local state +- A global store that exposes reactive state to UI components +- Authentication integration that supplies auth tokens for secure subscriptions +- Serverless functions that process payment webhooks and update subscription-related data +- Database schema migrations defining tables and policies +- A service worker for offline caching and background sync + +```mermaid +graph TB +Client["Browser Client"] +Store["Global Store (React)"] +Sync["Sync Layer"] +Supabase["Supabase Client"] +RT["Supabase Realtime (WebSocket)"] +DB["PostgreSQL"] +Auth["Supabase Auth"] +Webhooks["Payment Webhooks"] +SW["Service Worker"] +Client --> Store +Store --> Sync +Sync --> Supabase +Supabase --> RT +RT --> DB +Supabase --> Auth +Webhooks --> DB +SW --> Client +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [public/sw.js](file://public/sw.js) + +**Section sources** +- [README.md](file://README.md) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [public/sw.js](file://public/sw.js) + +## Core Components +- Supabase client setup and configuration for real-time channels and authentication +- Synchronization module that subscribes to table-level events and maintains a normalized local cache +- Global store exposing reactive state and actions to React components +- Authentication integration ensuring only authenticated users subscribe to protected channels +- Payment webhook handlers updating subscription status in the database +- Service worker providing offline caching and background synchronization + +Key responsibilities: +- Establish and manage WebSocket connections to Supabase Realtime +- Authenticate connections using Supabase auth tokens +- Subscribe to specific channels and events (e.g., job applications, user profiles, subscriptions) +- Normalize incoming payloads and merge with local state +- Handle reconnection, backoff, and error recovery +- Persist critical state for offline access and reconcile when online + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [public/sw.js](file://public/sw.js) + +## Architecture Overview +The real-time architecture leverages Supabase Realtime over WebSockets. The client authenticates with Supabase, subscribes to channels scoped to tables or rows, and receives change events. The sync layer normalizes these events into a local store, which drives UI updates. Payment webhooks trigger server-side updates that propagate to clients via Realtime. + +```mermaid +sequenceDiagram +participant UI as "UI Components" +participant Store as "Global Store" +participant Sync as "Sync Layer" +participant SB as "Supabase Client" +participant RT as "Realtime WS" +participant DB as "PostgreSQL" +participant WH as "Webhook Handlers" +UI->>Store : Request data / subscribe +Store->>Sync : Initialize subscriptions +Sync->>SB : Connect with auth token +SB->>RT : Open channel(s) +RT-->>SB : Event payload (insert/update/delete) +SB-->>Sync : Normalized event +Sync->>DB : Query initial snapshot if needed +DB-->>Sync : Snapshot data +Sync->>Store : Update normalized state +Store-->>UI : Trigger re-render +WH->>DB : Update subscription status +DB-->>RT : Emit change event +RT-->>SB : Subscription change event +SB-->>Sync : Process event +Sync->>Store : Merge and persist +Store-->>UI : Reflect updated subscription +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Supabase Client and Realtime Channels +- Initializes the Supabase client with project URL and anon/public keys +- Configures realtime channels for relevant tables +- Ensures channels are subscribed only after successful authentication +- Manages channel lifecycle (subscribe/unsubscribe) and error callbacks + +Implementation highlights: +- Channel names typically follow a pattern like “table:” +- Filters can be applied to limit events to specific rows or columns +- Error handling includes logging and triggering reconnection logic + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) + +### Synchronization Layer +- Subscribes to insert, update, and delete events for key tables +- Normalizes payloads into a consistent shape +- Merges changes into local state while preserving referential integrity +- Handles conflicts by applying last-write-wins or custom merge rules +- Persists snapshots to IndexedDB for offline access + +Event processing flow: +```mermaid +flowchart TD +Start(["Receive Event"]) --> Parse["Parse Payload"] +Parse --> Validate{"Valid Schema?"} +Validate --> |No| LogError["Log and Ignore"] +Validate --> |Yes| Normalize["Normalize Record"] +Normalize --> Merge["Merge Into Local State"] +Merge --> Conflict{"Conflict Detected?"} +Conflict --> |Yes| Resolve["Apply Conflict Resolution"] +Conflict --> |No| Persist["Persist Snapshot"] +Resolve --> Persist +Persist --> Notify["Notify Store/UI"] +LogError --> End(["Done"]) +Notify --> End +``` + +**Diagram sources** +- [src/lib/sync.js](file://src/lib/sync.js) + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) + +### Global Store and React Integration +- Exposes reactive state slices for job applications, user profiles, and subscriptions +- Provides actions to subscribe/unsubscribe and clear caches +- Integrates with React hooks for efficient re-renders +- Coordinates with the sync layer to ensure consistency + +Usage patterns: +- Components subscribe to slices they need +- Actions dispatch side effects (e.g., fetch initial data) +- Store persists critical slices to storage for resilience + +**Section sources** +- [src/store.jsx](file://src/store.jsx) + +### Authentication and Token Management +- Authenticates users via Supabase Auth +- Supplies session tokens to realtime channels +- Handles token refresh and logout scenarios +- Ensures channels are closed upon logout + +Security considerations: +- Only authenticated sessions can subscribe to protected channels +- Row-level security policies enforce per-user access + +**Section sources** +- [src/auth.jsx](file://src/auth.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) + +### Payment Webhooks and Subscription Updates +- PayMongo and PayPal webhook handlers validate signatures and payloads +- Update subscription records in the database +- Realtime emits change events to clients reflecting new subscription status + +Operational notes: +- Idempotent processing to handle duplicate deliveries +- Error retries and dead-lettering for failed events + +**Section sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Offline Support and Service Worker +- Caches essential data for offline viewing +- Queues mutations when offline and replays them when reconnected +- Background sync ensures eventual consistency + +Offline strategy: +- Cache-first retrieval for read operations +- Queue writes and retry on connectivity restoration + +**Section sources** +- [public/sw.js](file://public/sw.js) + +## Dependency Analysis +The following diagram shows how core modules depend on each other and external services: + +```mermaid +graph LR +Store["store.jsx"] --> Sync["sync.js"] +Sync --> Supabase["supabase.js"] +Supabase --> Auth["auth.jsx"] +Supabase --> RT["Supabase Realtime"] +RT --> DB["PostgreSQL"] +WH1["paymongo-webhook/index.ts"] --> DB +WH2["paypal-webhook/index.ts"] --> DB +SW["sw.js"] --> Store +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/auth.jsx](file://src/auth.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [public/sw.js](file://public/sw.js) + +**Section sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/auth.jsx](file://src/auth.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [public/sw.js](file://public/sw.js) + +## Performance Considerations +- Prefer column-specific filters on realtime subscriptions to reduce payload size +- Use normalized state to avoid redundant renders; memoize derived data +- Debounce high-frequency events (e.g., typing indicators) before UI updates +- Batch mutations where possible and apply optimistic updates with rollback on failure +- Implement exponential backoff with jitter for reconnections +- Cache frequently accessed data in IndexedDB and serve from cache first +- Limit subscription scopes to necessary tables and rows using RLS policies + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Connection failures: Check network availability, verify Supabase project URL and keys, inspect browser console for WebSocket errors +- Authentication errors: Ensure valid session exists; handle token refresh and logout flows; confirm RLS policies allow access +- Missing updates: Verify channel names and filters; check server-side webhook logs; confirm database triggers emit events +- Conflicts: Inspect conflict resolution logic; consider adding version fields or timestamps for deterministic merges +- Offline behavior: Confirm service worker registration and cache strategies; validate queued mutations replay correctly + +Diagnostic steps: +- Log channel lifecycle events (connect, subscribe, unsubscribe, error) +- Track event counts and latency metrics +- Compare local snapshot with server snapshot after reconnects +- Review webhook delivery and idempotency keys + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [public/sw.js](file://public/sw.js) + +## Conclusion +ApplyGuard PH uses Supabase Realtime over WebSockets to provide live synchronization across job applications, user profiles, and subscription statuses. The architecture separates concerns between client authentication, channel management, normalization, and persistence, enabling robust offline support and scalable real-time updates. By following the recommended patterns for connection management, reconnection, conflict resolution, and performance optimization, teams can maintain responsive and reliable user experiences. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Message Protocols and Event Types +- Channel naming convention: “table:” +- Event types: insert, update, delete +- Payload structure: normalized record plus metadata (event type, timestamp, user ID) +- Filters: row-level predicates based on user context and RLS policies + +Example event references: +- Job application updates: insert/update/delete on applications table +- User profile changes: update on profiles table +- Subscription status modifications: update on subscriptions table + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Data Models +The following entities participate in real-time updates: + +```mermaid +erDiagram +USER { +uuid id PK +string email UK +string name +timestamp created_at +timestamp updated_at +} +APPLICATION { +uuid id PK +uuid user_id FK +string company +string role +enum status +timestamp applied_at +timestamp updated_at +} +SUBSCRIPTION { +uuid id PK +uuid user_id FK +enum plan +boolean active +timestamp expires_at +timestamp updated_at +} +USER ||--o{ APPLICATION : creates +USER ||--o{ SUBSCRIPTION : owns +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Client-Side Implementation Examples +- Establishing a realtime connection and subscribing to channels after authentication +- Handling insert/update/delete events and merging into normalized state +- Managing reconnection with exponential backoff and jitter +- Persisting snapshots to IndexedDB and reconciling on reconnect +- Dispatching store actions to reflect changes in the UI + +References: +- Supabase client setup and channel configuration +- Sync layer event processing and normalization +- Store actions and hooks for reactive updates +- Authentication integration for secure subscriptions +- Service worker caching and background sync + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [public/sw.js](file://public/sw.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/AI Proxy Service.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/AI Proxy Service.md new file mode 100644 index 0000000..cb160c6 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/AI Proxy Service.md @@ -0,0 +1,333 @@ +# AI Proxy Service + + +**Referenced Files in This Document** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides detailed API documentation for the AI Proxy Edge Function that routes and proxies AI model requests on behalf of clients. It covers request routing, response streaming, authentication using Supabase JWT tokens, prompt management integration, rate limiting strategies, security considerations, client implementation examples, error handling patterns, timeout configurations, and performance optimization tips. + +## Project Structure +The AI proxy is implemented as a Supabase Edge Function with shared utilities and frontend integrations: +- supabase/functions/ai-proxy/index.ts: Entry point for the proxy edge function +- supabase/functions/_shared/http.ts: HTTP helpers used by the proxy +- supabase/functions/_shared/prompts.ts: Prompt management utilities +- src/lib/ai.js: Client-side AI orchestration +- src/lib/prompt.js: Prompt composition helpers +- src/lib/tone.js: Tone analysis helper +- src/components/AiAssistant.jsx: UI component invoking AI features + +```mermaid +graph TB +subgraph "Client" +FE["Frontend (AiAssistant.jsx)"] +LibAI["Client AI Lib (ai.js)"] +LibPrompt["Prompt Builder (prompt.js)"] +LibTone["Tone Analyzer (tone.js)"] +end +subgraph "Supabase Edge Functions" +Proxy["AI Proxy (ai-proxy/index.ts)"] +SharedHTTP["Shared HTTP (http.ts)"] +Prompts["Prompts (prompts.ts)"] +end +subgraph "External AI Providers" +Provider["AI Model APIs"] +end +FE --> LibAI +LibAI --> LibPrompt +LibAI --> LibTone +LibAI --> Proxy +Proxy --> SharedHTTP +Proxy --> Prompts +Proxy --> Provider +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Core Components +- AI Proxy Edge Function: Validates Supabase JWT, parses typed requests, resolves prompts, forwards to external AI providers, streams responses when supported, and returns standardized JSON or SSE events. +- Shared HTTP Utilities: Provides consistent request/response wrappers, headers, timeouts, and streaming helpers. +- Prompt Management: Loads and composes prompts from configuration or storage, enabling dynamic prompt templates and versioning. +- Client AI Library: Orchestrates calls to the proxy, handles retries, timeouts, and SSE parsing on the client side. +- Prompt Builder: Composes structured prompts for resume analysis, interview questions, and tone analysis. +- Tone Analyzer: Prepares inputs for tone analysis endpoints. +- AiAssistant Component: User-facing UI that triggers AI flows and renders results. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Architecture Overview +The AI Proxy sits between the client and external AI providers. It enforces authentication, applies rate limits, manages prompts, and supports both JSON and streaming responses. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Proxy as "AI Proxy Edge Function" +participant HTTP as "Shared HTTP" +participant Prompts as "Prompts Manager" +participant Provider as "AI Provider API" +Client->>Proxy : "POST /v1/ai/proxy" + JWT +Proxy->>Proxy : "Validate Supabase JWT" +Proxy->>Prompts : "Resolve prompt template" +Prompts-->>Proxy : "Compiled prompt" +Proxy->>HTTP : "Forward request with headers/timeouts" +alt "Streaming enabled" +HTTP-->>Proxy : "SSE stream chunks" +Proxy-->>Client : "SSE events" +else "Non-streaming" +HTTP-->>Proxy : "JSON response" +Proxy-->>Client : "JSON payload" +end +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Detailed Component Analysis + +### AI Proxy Edge Function API +- Endpoint: POST /v1/ai/proxy +- Authentication: Requires a valid Supabase JWT in the Authorization header as Bearer token. The proxy validates the token before processing. +- Request Body Schema: + - action: string — one of "resume_analysis", "interview_questions", "tone_analysis" + - prompt_key: string — key identifying the prompt template to use + - variables: object — dynamic values injected into the prompt template + - provider: string — target AI provider identifier + - model: string — model name or variant + - stream: boolean — enable server-sent events (SSE) streaming + - options: object — provider-specific parameters (e.g., temperature, max_tokens) +- Response Formats: + - Non-streaming: JSON with fields such as content, usage, and metadata + - Streaming: SSE events with incremental chunks and final completion event +- Error Responses: + - 401 Unauthorized if JWT is missing or invalid + - 400 Bad Request for malformed payloads or unsupported actions + - 429 Too Many Requests when rate limit exceeded + - 5xx errors proxied from upstream providers with normalized error bodies + +```mermaid +flowchart TD +Start(["Request Received"]) --> Auth["Validate Supabase JWT"] +Auth --> |Invalid| Err401["Return 401 Unauthorized"] +Auth --> |Valid| Parse["Parse and Validate Body"] +Parse --> |Invalid| Err400["Return 400 Bad Request"] +Parse --> Resolve["Resolve Prompt Template"] +Resolve --> RateLimit{"Rate Limit OK?"} +RateLimit --> |No| Err429["Return 429 Too Many Requests"] +RateLimit --> |Yes| Forward["Forward to Provider"] +Forward --> Stream{"Stream Enabled?"} +Stream --> |Yes| SSE["Emit SSE Events"] +Stream --> |No| JSON["Return JSON Response"] +SSE --> End(["Done"]) +JSON --> End +Err401 --> End +Err400 --> End +Err429 --> End +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Authentication and Security +- JWT Validation: The proxy checks the Supabase JWT signature and claims before forwarding any request. +- Header Sanitization: Only whitelisted headers are forwarded to providers; sensitive headers are stripped. +- Input Validation: Strict schema validation prevents injection and ensures safe prompt templating. +- Secrets Management: Provider keys are accessed via environment variables configured at runtime. +- Rate Limiting: Per-user or per-token limits enforced to protect upstream services. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Prompt Management Integration +- Prompt Resolution: The proxy uses a prompt manager to load templates by key and inject variables safely. +- Versioning: Templates can be versioned and selected based on action or feature flags. +- Safety: Variables are escaped and validated to prevent prompt injection. + +**Section sources** +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Client Implementation Examples +- Resume Analysis: + - Action: "resume_analysis" + - Inputs: resume text, job description, optional scoring criteria + - Output: structured analysis including strengths, gaps, and recommendations +- Interview Questions: + - Action: "interview_questions" + - Inputs: role, seniority, tech stack, focus areas + - Output: curated question set with difficulty levels and expected answers +- Tone Analysis: + - Action: "tone_analysis" + - Inputs: message or email text + - Output: sentiment, tone classification, and suggestions + +```mermaid +sequenceDiagram +participant UI as "AiAssistant.jsx" +participant AILib as "ai.js" +participant PromptLib as "prompt.js" +participant ToneLib as "tone.js" +participant Proxy as "AI Proxy" +UI->>AILib : "Trigger flow (resume/interview/tone)" +AILib->>PromptLib : "Build prompt variables" +AILib->>ToneLib : "Prepare tone input (if applicable)" +AILib->>Proxy : "POST /v1/ai/proxy with action + body" +Proxy-->>AILib : "JSON or SSE stream" +AILib-->>UI : "Render results" +``` + +**Diagram sources** +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) + +### Error Handling Patterns +- Normalized Errors: All upstream errors are mapped to consistent JSON structures with codes and messages. +- Retry Strategy: Exponential backoff with jitter for transient failures. +- Timeouts: Configurable request timeouts and SSE read timeouts to avoid hanging connections. +- Graceful Degradation: Fallback models or cached responses when available. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Rate Limiting Strategies +- Token-based Limits: Enforce per-Supabase-user quotas to prevent abuse. +- Global Caps: Apply global caps per action type to protect provider stability. +- Backpressure: Return 429 with retry-after hints when limits are hit. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +### Performance Optimization Tips +- Enable Streaming: Use stream=true for long outputs to reduce latency and memory usage. +- Cache Prompts: Reuse compiled prompts where possible to minimize overhead. +- Batch Requests: Combine multiple small queries into single calls when supported. +- Tune Options: Adjust temperature and max_tokens to balance quality and cost. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +The proxy depends on shared HTTP utilities and prompt management, while the client relies on AI orchestration libraries and UI components. + +```mermaid +graph LR +Proxy["ai-proxy/index.ts"] --> HTTP["_shared/http.ts"] +Proxy --> Prompts["_shared/prompts.ts"] +ClientAI["lib/ai.js"] --> Proxy +ClientAI --> PromptLib["lib/prompt.js"] +ClientAI --> ToneLib["lib/tone.js"] +UI["components/AiAssistant.jsx"] --> ClientAI +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [lib/ai.js](file://src/lib/ai.js) +- [lib/prompt.js](file://src/lib/prompt.js) +- [lib/tone.js](file://src/lib/tone.js) +- [components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Performance Considerations +- Prefer streaming for large outputs to improve perceived latency. +- Set appropriate timeouts to fail fast on slow providers. +- Use efficient prompt templates to reduce token usage. +- Monitor provider response times and adjust concurrency accordingly. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +- 401 Unauthorized: Ensure the Authorization header contains a valid Supabase JWT. +- 400 Bad Request: Verify action, prompt_key, and variables match expected schemas. +- 429 Too Many Requests: Implement retry with backoff and respect retry-after hints. +- Timeouts: Increase timeout settings or switch to non-streaming mode for heavy tasks. +- Provider Errors: Inspect normalized error bodies for upstream status codes and messages. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +The AI Proxy Edge Function centralizes authentication, prompt management, rate limiting, and provider communication, offering a secure and efficient interface for AI features. By following the documented API, error handling patterns, and performance tips, clients can reliably integrate resume analysis, interview question generation, and tone analysis capabilities. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Request/Response Schemas Summary +- Actions: "resume_analysis", "interview_questions", "tone_analysis" +- Headers: Authorization: Bearer +- Body Fields: action, prompt_key, variables, provider, model, stream, options +- Responses: JSON payload or SSE events with chunked data and completion markers + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Billing & Payment Functions.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Billing & Payment Functions.md new file mode 100644 index 0000000..00ea286 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Billing & Payment Functions.md @@ -0,0 +1,595 @@ +# Billing & Payment Functions + + +**Referenced Files in This Document** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive API documentation for billing and payment-related Edge Functions, including checkout creation endpoints for PayMongo and PayPal, webhook handlers for payment processing, order capture functions, and subscription cancellation services. It specifies HTTP methods, URL patterns, request/response schemas, webhook payload formats, signature verification, idempotency considerations, error handling strategies, security best practices, and client implementation examples. It also covers webhook retry mechanisms, failure handling, and monitoring approaches. + +## Project Structure +The billing and payment system is implemented as Supabase Edge Functions with shared utilities and database migrations: + +- Checkout creation: create-checkout (PayMongo), create-paypal-order (PayPal) +- Webhooks: paymongo-webhook, paypal-webhook +- Order capture: capture-paypal-order +- Subscription management: cancel-subscription +- Shared utilities: http, paypal runtime and helpers, entitlements +- Database schema: 001_schema.sql, 002_paypal_fulfillment.sql + +```mermaid +graph TB +subgraph "Edge Functions" +CC["create-checkout/index.ts"] +PMW["paymongo-webhook/index.ts"] +CPO["create-paypal-order/index.ts"] +CPOC["capture-paypal-order/index.ts"] +PW["paypal-webhook/index.ts"] +CS["cancel-subscription/index.ts"] +end +subgraph "Shared Utilities" +SH_HTTP["_shared/http.ts"] +SH_PR["_shared/paypal-runtime.ts"] +SH_PP["_shared/paypal.ts"] +SH_ENT["_shared/entitlement.ts"] +end +subgraph "Database" +DB1["migrations/001_schema.sql"] +DB2["migrations/002_paypal_fulfillment.sql"] +end +CC --> SH_HTTP +CC --> SH_ENT +PMW --> SH_ENT +CPO --> SH_PR +CPO --> SH_PP +CPOC --> SH_ENT +PW --> SH_ENT +CS --> SH_ENT +CC --> DB1 +PMW --> DB1 +CPO --> DB1 +CPOC --> DB2 +PW --> DB2 +CS --> DB1 +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Create Checkout (PayMongo): Creates a PayMongo checkout session and returns a redirect URL to complete payment. +- PayMongo Webhook: Receives PayMongo events, verifies signatures, updates order status, and fulfills entitlements. +- Create PayPal Order: Creates a PayPal order via the PayPal runtime and returns order details for client approval. +- Capture PayPal Order: Captures an approved PayPal order and fulfills entitlements upon success. +- PayPal Webhook: Processes PayPal events, verifies signatures, updates order state, and manages subscriptions. +- Cancel Subscription: Cancels an active subscription and revokes entitlements accordingly. + +Key responsibilities: +- Securely interact with external payment providers using environment variables. +- Enforce idempotency on webhooks and captures. +- Update database records for orders and subscriptions. +- Grant or revoke user entitlements based on payment outcomes. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Architecture Overview +The payment architecture integrates client flows with provider-specific Edge Functions and shared entitlement logic. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CC as "create-checkout (PayMongo)" +participant PM as "PayMongo API" +participant PMW as "paymongo-webhook" +participant Ent as "Entitlements" +participant DB as "Database" +Client->>CC : POST /functions/v1/create-checkout {planId, userId} +CC->>PM : Create checkout session +PM-->>CC : {checkout_url} +CC-->>Client : {checkout_url} +Note over Client,PM : User completes payment on PayMongo +PM->>PMW : POST /functions/v1/paymongo-webhook {event, metadata} +PMW->>DB : Upsert order/payment record +PMW->>Ent : Grant entitlements +Ent-->>PMW : Success/Failure +PMW-->>PM : 200 OK +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CPO as "create-paypal-order" +participant PR as "PayPal Runtime" +participant PP as "PayPal API" +participant CPOC as "capture-paypal-order" +participant PW as "paypal-webhook" +participant Ent as "Entitlements" +participant DB as "Database" +Client->>CPO : POST /functions/v1/create-paypal-order {planId, userId} +CPO->>PR : Build order request +PR->>PP : CreateOrder +PP-->>PR : {order_id, status} +PR-->>CPO : {order_id, approve_url} +CPO-->>Client : {order_id, approve_url} +Client->>CPOC : POST /functions/v1/capture-paypal-order {order_id} +CPOC->>PR : CaptureOrder +PR->>PP : Capture order +PP-->>PR : {status, transaction_id} +CPOC->>DB : Record capture result +CPOC->>Ent : Grant entitlements +Ent-->>CPOC : Success/Failure +CPOC-->>Client : {success} +PP->>PW : POST /functions/v1/paypal-webhook {event, resource} +PW->>DB : Update order/subscription state +PW->>Ent : Fulfill or revoke entitlements +PW-->>PP : 200 OK +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Create Checkout (PayMongo) +- Purpose: Create a PayMongo checkout session and return a URL for the client to redirect users to complete payment. +- HTTP Method: POST +- URL Pattern: /functions/v1/create-checkout +- Request Body: + - planId: string — identifier for the product/plan + - userId: string — authenticated user identifier + - currency?: string — ISO currency code (optional) + - amount?: number — total amount in minor units (optional) + - metadata?: object — arbitrary key-value pairs forwarded to provider +- Response Body: + - checkout_url: string — PayMongo hosted checkout page + - id: string — internal checkout reference + - status: string — initial status (e.g., pending) +- Error Responses: + - 400 Bad Request: Missing required fields + - 500 Internal Server Error: Provider or network errors +- Idempotency: Not applicable at creation; rely on webhook idempotency for fulfillment. +- Security: + - Validate authentication context for userId + - Use environment variables for provider credentials + - Sanitize and validate inputs + +```mermaid +flowchart TD +Start(["POST /create-checkout"]) --> Validate["Validate request body and auth"] +Validate --> CallProvider["Create PayMongo checkout session"] +CallProvider --> ProviderOK{"Provider response OK?"} +ProviderOK --> |Yes| ReturnURL["Return checkout_url and id"] +ProviderOK --> |No| HandleError["Return error with message"] +ReturnURL --> End(["Done"]) +HandleError --> End +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +### PayMongo Webhook +- Purpose: Receive PayMongo events, verify signatures, update order/payment records, and fulfill entitlements. +- HTTP Method: POST +- URL Pattern: /functions/v1/paymongo-webhook +- Headers: + - X-PayMongo-Signature: string — signature header for verification +- Request Body: + - event: object — PayMongo event payload + - data: object — event data (payment, checkout, etc.) + - metadata: object — original metadata from checkout creation +- Signature Verification: + - Verify HMAC signature using shared secret from environment + - Reject requests with invalid or missing signatures +- Processing Logic: + - Identify event type (e.g., payment.paid, checkout.completed) + - Lookup order by metadata.orderId + - Update order status and payment details + - Grant entitlements if payment succeeded +- Idempotency: + - Deduplicate events by event.id + - Skip processing if already fulfilled +- Response: + - 200 OK on successful processing + - 400/401/403 for invalid signatures + - 500 for internal errors +- Error Handling: + - Log failures and continue processing other events + - Retry strategy managed by provider; function should be idempotent + +```mermaid +flowchart TD +Start(["POST /paymongo-webhook"]) --> VerifySig["Verify X-PayMongo-Signature"] +VerifySig --> SigOK{"Signature valid?"} +SigOK --> |No| Reject["Return 401 Unauthorized"] +SigOK --> |Yes| ParseEvent["Parse event and metadata"] +ParseEvent --> Dedup["Check idempotency by event.id"] +Dedup --> AlreadyProcessed{"Already processed?"} +AlreadyProcessed --> |Yes| Ack["Return 200 OK"] +AlreadyProcessed --> |No| UpdateOrder["Update order/payment records"] +UpdateOrder --> Fulfill["Grant entitlements"] +Fulfill --> Done["Return 200 OK"] +Reject --> End(["End"]) +Ack --> End +Done --> End +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Create PayPal Order +- Purpose: Create a PayPal order and return approval details for the client to finalize. +- HTTP Method: POST +- URL Pattern: /functions/v1/create-paypal-order +- Request Body: + - planId: string — product/plan identifier + - userId: string — authenticated user identifier + - currency?: string — ISO currency code + - amount?: number — total amount in minor units + - metadata?: object — additional context +- Response Body: + - order_id: string — PayPal order identifier + - approve_url: string — client-side approval URL + - status: string — initial order status +- Error Responses: + - 400 Bad Request: Invalid input + - 500 Internal Server Error: PayPal API or runtime errors +- Security: + - Validate authentication context + - Use PayPal runtime to manage tokens securely + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CPO as "create-paypal-order" +participant PR as "PayPal Runtime" +participant PP as "PayPal API" +Client->>CPO : POST /create-paypal-order {planId, userId, ...} +CPO->>PR : Build order request +PR->>PP : CreateOrder +PP-->>PR : {order_id, status} +PR-->>CPO : {order_id, approve_url} +CPO-->>Client : {order_id, approve_url} +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +### Capture PayPal Order +- Purpose: Capture an approved PayPal order and fulfill entitlements upon success. +- HTTP Method: POST +- URL Pattern: /functions/v1/capture-paypal-order +- Request Body: + - order_id: string — PayPal order identifier + - userId: string — authenticated user identifier +- Response Body: + - success: boolean — capture outcome + - transaction_id?: string — PayPal transaction identifier + - status: string — updated order status +- Error Responses: + - 400 Bad Request: Missing order_id + - 404 Not Found: Order not found + - 500 Internal Server Error: Capture or fulfillment errors +- Idempotency: + - Check existing capture status before processing + - Avoid duplicate captures +- Security: + - Validate ownership of order_id against userId + - Ensure only approved orders are captured + +```mermaid +flowchart TD +Start(["POST /capture-paypal-order"]) --> Validate["Validate order_id and userId"] +Validate --> CheckStatus["Check order status and approvals"] +CheckStatus --> Approved{"Order approved?"} +Approved --> |No| ReturnError["Return error"] +Approved --> |Yes| Capture["Capture order via PayPal Runtime"] +Capture --> CaptureOK{"Capture success?"} +CaptureOK --> |Yes| Fulfill["Grant entitlements"] +Fulfill --> ReturnSuccess["Return success and transaction_id"] +CaptureOK --> |No| ReturnError +ReturnError --> End(["End"]) +ReturnSuccess --> End +``` + +**Diagram sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### PayPal Webhook +- Purpose: Process PayPal events, verify signatures, update order/subscription state, and manage entitlements. +- HTTP Method: POST +- URL Pattern: /functions/v1/paypal-webhook +- Headers: + - PayPal-Auth-Algorithm: string — algorithm used for signature + - PayPal-Transmission-ID: string — unique transmission ID + - PayPal-Transmission-Time: string — timestamp + - PayPal-Cert-URL: string — certificate URL + - PayPal-Signature: string — signature value +- Request Body: + - event_type: string — PayPal event type + - resource: object — event resource (order, subscription, etc.) + - metadata?: object — custom metadata +- Signature Verification: + - Verify signature using provided certificate and algorithm + - Validate transmission metadata +- Processing Logic: + - Map event types to actions (e.g., ORDER.APPROVED, BILLING.SUBSCRIPTION.CANCELLED) + - Update order/subscription records + - Grant or revoke entitlements based on event +- Idempotency: + - Deduplicate by transmission.id + - Skip if already processed +- Response: + - 200 OK on successful processing + - 400/401/403 for invalid signatures or malformed payloads + - 500 for internal errors + +```mermaid +flowchart TD +Start(["POST /paypal-webhook"]) --> VerifySig["Verify PayPal signature and headers"] +VerifySig --> SigOK{"Signature valid?"} +SigOK --> |No| Reject["Return 401 Unauthorized"] +SigOK --> |Yes| Dedup["Deduplicate by transmission.id"] +Dedup --> Already{"Already processed?"} +Already --> |Yes| Ack["Return 200 OK"] +Already --> |No| Dispatch["Dispatch by event_type"] +Dispatch --> UpdateState["Update order/subscription state"] +UpdateState --> ManageEnt["Grant/revoke entitlements"] +ManageEnt --> Done["Return 200 OK"] +Reject --> End(["End"]) +Ack --> End +Done --> End +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Cancel Subscription +- Purpose: Cancel an active subscription and revoke associated entitlements. +- HTTP Method: POST +- URL Pattern: /functions/v1/cancel-subscription +- Request Body: + - subscriptionId: string — provider subscription identifier + - userId: string — authenticated user identifier + - reason?: string — optional cancellation reason +- Response Body: + - success: boolean — cancellation outcome + - status: string — updated subscription status +- Error Responses: + - 400 Bad Request: Missing subscriptionId or userId + - 404 Not Found: Subscription not found + - 500 Internal Server Error: Provider or internal errors +- Security: + - Validate ownership of subscriptionId against userId + - Ensure only active subscriptions can be cancelled +- Post-Cancellation: + - Revoke entitlements immediately or at period end depending on policy + - Update database records + +```mermaid +flowchart TD +Start(["POST /cancel-subscription"]) --> Validate["Validate subscriptionId and userId"] +Validate --> FetchSub["Fetch subscription details"] +FetchSub --> Active{"Subscription active?"} +Active --> |No| ReturnError["Return error"] +Active --> |Yes| CancelProv["Cancel subscription with provider"] +CancelProv --> CancelOK{"Cancellation success?"} +CancelOK --> |Yes| RevokeEnt["Revoke entitlements"] +RevokeEnt --> ReturnSuccess["Return success and status"] +CancelOK --> |No| ReturnError +ReturnError --> End(["End"]) +ReturnSuccess --> End +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Dependency Analysis +The following diagram shows dependencies between Edge Functions and shared modules: + +```mermaid +graph LR +CC["create-checkout/index.ts"] --> SH_HTTP["_shared/http.ts"] +CC --> SH_ENT["_shared/entitlement.ts"] +PMW["paymongo-webhook/index.ts"] --> SH_ENT +CPO["create-paypal-order/index.ts"] --> SH_PR["_shared/paypal-runtime.ts"] +CPO --> SH_PP["_shared/paypal.ts"] +CPOC["capture-paypal-order/index.ts"] --> SH_ENT +PW["paypal-webhook/index.ts"] --> SH_ENT +CS["cancel-subscription/index.ts"] --> SH_ENT +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Performance Considerations +- Minimize external API calls by caching provider responses where safe. +- Use connection pooling and timeouts when calling external APIs. +- Keep webhook handlers fast and idempotent; offload heavy work to background jobs if needed. +- Batch entitlement updates when possible to reduce database writes. +- Monitor latency and error rates for each provider integration. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid webhook signatures: + - Ensure correct secrets and algorithms are configured + - Verify headers and payload integrity +- Duplicate processing: + - Confirm idempotency keys are used and checked +- Failed entitlement grants: + - Check provider responses and database constraints + - Implement retries with exponential backoff for transient errors +- Network timeouts: + - Increase timeouts and implement circuit breakers +- Logging and monitoring: + - Add structured logs for all critical steps + - Track metrics for success/failure rates and latencies + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Conclusion +The billing and payment system provides robust, secure, and idempotent workflows for both one-time payments and subscriptions across PayMongo and PayPal. By leveraging shared utilities for HTTP and provider interactions, and centralized entitlement management, the system ensures consistent fulfillment and reliable error handling. Proper signature verification, idempotency checks, and monitoring are essential to maintain reliability and security. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Client Implementation Examples +- PayMongo One-Time Payment Flow: + - Initiate checkout via create-checkout endpoint + - Redirect user to returned checkout_url + - Wait for webhook confirmation before granting access +- PayPal One-Time Payment Flow: + - Create order via create-paypal-order + - Approve order on client side using approve_url + - Capture order via capture-paypal-order + - Fulfill entitlements upon success +- PayPal Subscription Management: + - Create subscription through provider flow + - Listen to paypal-webhook events for lifecycle changes + - Cancel subscription via cancel-subscription endpoint + +[No sources needed since this section provides conceptual guidance] + +### Webhook Retry Mechanisms and Failure Handling +- Providers may retry failed deliveries; ensure functions are idempotent +- Implement deduplication using event IDs or transmission IDs +- Log all webhook attempts and outcomes for observability +- Use dead-letter queues for failed events requiring manual intervention + +[No sources needed since this section provides conceptual guidance] + +### Monitoring Approaches +- Track success/failure rates per endpoint +- Measure latency percentiles for provider calls +- Alert on signature verification failures and idempotency collisions +- Correlate logs with database state changes for audits + +[No sources needed since this section provides conceptual guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Checkout Creation Functions.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Checkout Creation Functions.md new file mode 100644 index 0000000..8542476 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Checkout Creation Functions.md @@ -0,0 +1,310 @@ +# Checkout Creation Functions + + +**Referenced Files in This Document** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Security Considerations](#security-considerations) +10. [Conclusion](#conclusion) + +## Introduction +This document provides detailed API documentation for the checkout creation function used to initiate subscription-based payments. It covers the HTTP endpoint, request parameters (including user authentication, pricing tier selection, and currency configuration), response schema (checkout session details, payment method options, and redirect URLs), implementation examples for different subscription plans, error handling scenarios, and security considerations such as input validation, rate limiting, and fraud prevention. + +## Project Structure +The checkout creation flow is implemented as a serverless function within the Supabase Edge Functions runtime. The core logic resides in the create-checkout function, which integrates with shared entitlement utilities, HTTP helpers, and frontend billing libraries for pricing and client-side orchestration. + +```mermaid +graph TB +Client["Client App"] --> CF["Supabase Edge Function
create-checkout"] +CF --> Ent["Shared Entitlements
entitlement.ts"] +CF --> Http["HTTP Helpers
http.ts"] +CF --> DB["Supabase Database"] +CF --> Pay["Payment Provider"] +Client --> Pricing["Frontend Pricing Config
pricing.js"] +Client --> Billing["Billing Orchestration
billing.js"] +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +## Core Components +- Checkout Creation Function: Handles authenticated requests, validates inputs, resolves pricing tiers, constructs payment sessions, and returns redirect URLs and metadata. +- Shared Entitlements: Provides access control and entitlement checks relevant to checkout eligibility. +- HTTP Helpers: Encapsulates outbound calls to external services (e.g., payment provider). +- Frontend Billing Libraries: Provide pricing configuration and client-side orchestration for initiating checkout flows. + +Key responsibilities: +- Enforce user authentication and authorization before creating a checkout session. +- Validate pricing tier selection and supported currencies. +- Create a checkout session with the payment provider and return necessary client-side data. +- Return structured responses including redirect URLs and payment method options. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +## Architecture Overview +The checkout creation process follows a clear sequence from client initiation through server-side validation and payment provider integration. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant EdgeFn as "create-checkout Function" +participant Ent as "Entitlements" +participant Http as "HTTP Helpers" +participant Pay as "Payment Provider" +Client->>EdgeFn : "POST /functions/v1/create-checkout"
Headers : Authorization, Content-Type +EdgeFn->>EdgeFn : "Validate request body and headers" +EdgeFn->>Ent : "Check user entitlements and permissions" +Ent-->>EdgeFn : "Eligibility result" +EdgeFn->>Http : "Create checkout session with provider" +Http->>Pay : "Initialize payment session" +Pay-->>Http : "Session ID, redirect URL, payment methods" +Http-->>EdgeFn : "Provider response" +EdgeFn-->>Client : "Checkout session details and redirect URL" +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Detailed Component Analysis + +### HTTP Endpoint +- Method: POST +- Path: /functions/v1/create-checkout +- Authentication: Required via Authorization header (Bearer token or Supabase session context) +- Content-Type: application/json + +Request Parameters: +- user_id: Identifier of the authenticated user initiating checkout +- plan_id: Selected pricing tier identifier +- currency: ISO 4217 currency code (e.g., USD, EUR) +- success_url: Redirect URL after successful payment +- cancel_url: Redirect URL if the user cancels the payment +- metadata: Optional key-value pairs for tracking and analytics + +Response Schema: +- checkout_session_id: Unique identifier for the created checkout session +- redirect_url: Full URL to complete the payment +- payment_methods: Array of available payment method identifiers +- status: Current state of the checkout session (e.g., pending, completed, canceled) +- expires_at: Timestamp when the session expires +- metadata: Echoed request metadata for client correlation + +Example Response: +{ + "checkout_session_id": "cs_xxxxx", + "redirect_url": "https://provider.example.com/checkout/cs_xxxxx", + "payment_methods": ["card", "bank_transfer"], + "status": "pending", + "expires_at": "2025-01-01T00:00:00Z", + "metadata": { + "plan_id": "pro_monthly", + "currency": "USD" + } +} + +Implementation Examples: +- Basic monthly plan checkout: + - Request includes plan_id set to the monthly tier and currency configured to the user’s preferred currency. + - Success and cancel URLs point to appropriate client routes. +- Annual plan checkout with promotional metadata: + - Request includes plan_id for annual tier and additional metadata indicating promo codes or campaign IDs. +- Multi-currency support: + - Requests specify supported currency codes; backend validates against allowed currencies and maps to provider-specific amounts. + +Error Handling: +- Invalid request: Missing required fields or malformed JSON returns a 400-level error with descriptive message. +- Insufficient permissions: Unauthorized or forbidden responses indicate missing entitlements or invalid tokens. +- Service unavailability: Provider errors or timeouts return 500-level errors with retry guidance. + +Security Considerations: +- Input validation: Strict schema validation for all request fields. +- Rate limiting: Enforce per-user and global limits to prevent abuse. +- Fraud prevention: Validate plan_id and currency combinations, enforce idempotency keys, and log suspicious patterns. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +### Pricing Tier Selection +Pricing tiers are defined centrally and referenced by plan_id. The checkout function validates that the selected plan exists and is active for the given currency. + +- Supported plans: Monthly, Annual, Enterprise +- Currency mapping: Each plan has associated price points per currency +- Eligibility rules: Certain plans may require prior entitlement checks + +```mermaid +flowchart TD +Start(["Receive plan_id and currency"]) --> ValidatePlan["Validate plan_id exists and is active"] +ValidatePlan --> CheckCurrency["Map plan to currency-specific amount"] +CheckCurrency --> Allowed{"Allowed combination?"} +Allowed --> |No| Error["Return validation error"] +Allowed --> |Yes| Proceed["Proceed to session creation"] +Error --> End(["Exit"]) +Proceed --> End +``` + +**Diagram sources** +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### Currency Configuration +Currency configuration ensures that only supported currencies are accepted and mapped correctly to provider amounts. + +- Supported currencies: Defined in configuration and validated at runtime +- Conversion rules: Plan prices are converted based on predefined rates +- Locale considerations: Display formatting handled on the client side + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### User Authentication and Permissions +Authentication is enforced at the function boundary using Supabase Edge Functions context. Permissions are checked via shared entitlements to ensure users can purchase selected plans. + +- Authentication: Bearer token or session context validated +- Authorization: Entitlement checks determine eligibility for specific plans +- Session binding: Checkout session tied to authenticated user_id + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### Payment Method Options +Payment methods returned in the response reflect provider capabilities and regional availability. + +- Methods: Card, bank transfer, digital wallets (as supported by provider) +- Dynamic availability: Determined by provider response and user region +- Client rendering: UI adapts to available methods + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Redirect URLs +Redirect URLs guide users back to the application after payment completion or cancellation. + +- success_url: Post-payment landing page +- cancel_url: Cancellation fallback page +- Validation: URLs must be whitelisted and securely bound to the session + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +## Dependency Analysis +The checkout creation function depends on shared entitlements and HTTP helpers, while integrating with frontend billing libraries for pricing configuration and client orchestration. + +```mermaid +graph TB +CF["create-checkout/index.ts"] --> ENT["entitlement.ts"] +CF --> HTTP["http.ts"] +CF --> PRICING["pricing.js"] +CF --> BILLING["billing.js"] +CF --> PAY["Payment Provider"] +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +## Performance Considerations +- Minimize round-trips: Batch validation and provider calls where possible. +- Cache pricing configurations: Reduce repeated lookups for static plan definitions. +- Idempotency: Use idempotency keys to avoid duplicate charges and improve resilience. +- Timeouts and retries: Configure provider call timeouts and implement exponential backoff for transient failures. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid request: Ensure all required fields are present and correctly formatted. +- Insufficient permissions: Verify user entitlements and plan eligibility. +- Provider errors: Check network connectivity and provider status; retry with backoff. +- Redirect failures: Confirm success_url and cancel_url are whitelisted and accessible. + +Operational tips: +- Log request payloads and provider responses for diagnostics. +- Monitor error rates and latency metrics for the checkout function. +- Use structured error messages to aid client-side handling. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Security Considerations +Input validation: +- Enforce strict schemas for request bodies. +- Whitelist allowed plan_ids and currencies. +- Validate redirect URLs against an allowlist. + +Rate limiting: +- Apply per-user and global rate limits to mitigate abuse. +- Implement throttling for high-frequency requests. + +Fraud prevention: +- Require idempotency keys for checkout creation. +- Cross-check plan_id and currency combinations against known mappings. +- Detect anomalous patterns and flag for review. + +Access control: +- Enforce authentication and authorization at the function boundary. +- Use short-lived tokens and secure session management. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +The checkout creation function provides a secure, validated, and extensible entry point for initiating subscription payments. By enforcing strong authentication, validating pricing and currency selections, and returning comprehensive session details, it enables robust client-side checkout flows. Adhering to the security and performance recommendations ensures reliable operation and protection against common threats. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayMongo Webhook Handler.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayMongo Webhook Handler.md new file mode 100644 index 0000000..b50b9dd --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayMongo Webhook Handler.md @@ -0,0 +1,351 @@ +# PayMongo Webhook Handler + + +**Referenced Files in This Document** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion + +## Introduction +This document provides comprehensive webhook documentation for PayMongo payment processing within the project. It covers event types, payload structures, signature verification, idempotency and retry handling, error strategies, security best practices, and troubleshooting guidance. The implementation is a serverless function that receives PayMongo webhooks, validates them, processes events, updates subscription status, and ensures reliable delivery through idempotent operations. + +## Project Structure +The PayMongo webhook handler is implemented as a Supabase Edge Function. Related billing logic and shared utilities are located under the functions and lib directories. Documentation for the monetization plan and PayMongo integration is included in the docs folder. + +```mermaid +graph TB +subgraph "Supabase Functions" +A["paymongo-webhook/index.ts"] +B["_shared/entitlement.ts"] +C["_shared/http.ts"] +end +subgraph "Frontend Lib" +D["lib/billing.js"] +end +subgraph "Docs" +E["plans/monetization/03-subscriptions-paymongo.md"] +end +PayMongo["PayMongo Platform"] --> A +A --> B +A --> C +D --> A +E -. references .-> A +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Webhook endpoint: Receives HTTP POST requests from PayMongo, parses the body, verifies the signature, and dispatches to event handlers. +- Event handlers: Process specific event types such as payment.created, payment.completed, and payment.failed. They update subscription state and entitlements accordingly. +- Idempotency layer: Ensures duplicate events do not cause side effects by tracking processed event IDs. +- Security validation: Verifies webhook signatures using a secret and enforces secure configuration. +- Shared utilities: Provide HTTP helpers and entitlement management used across functions. + +Key responsibilities: +- Validate request origin and signature +- Parse and normalize payloads +- Apply idempotency checks +- Update subscription and entitlement records +- Return appropriate HTTP responses to signal success or failure + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Architecture Overview +The webhook flow involves receiving an event from PayMongo, validating it, processing the event, updating internal state (subscription and entitlements), and responding with success or error codes. + +```mermaid +sequenceDiagram +participant PM as "PayMongo" +participant WH as "Webhook Handler" +participant ENT as "Entitlement Manager" +participant DB as "Database" +PM->>WH : "POST /functions/v1/paymongo-webhook" +WH->>WH : "Parse JSON body" +WH->>WH : "Verify signature" +alt "Signature invalid" +WH-->>PM : "401 Unauthorized" +else "Signature valid" +WH->>WH : "Check idempotency (event ID)" +alt "Already processed" +WH-->>PM : "200 OK" +else "New event" +alt "Event type : payment.completed" +WH->>ENT : "Update subscription status" +ENT->>DB : "Persist changes" +DB-->>ENT : "OK" +ENT-->>WH : "OK" +WH-->>PM : "200 OK" +else "Event type : payment.failed" +WH->>ENT : "Mark subscription as failed" +ENT->>DB : "Persist changes" +DB-->>ENT : "OK" +ENT-->>WH : "OK" +WH-->>PM : "200 OK" +else "Other events" +WH-->>PM : "200 OK" +end +end +end +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Webhook Endpoint +Responsibilities: +- Accept POST requests at the designated function path +- Read and parse the JSON body +- Verify the webhook signature using the configured secret +- Route to event-specific handlers based on event type +- Enforce idempotency by checking previously processed event IDs +- Respond with appropriate HTTP status codes + +Security considerations: +- Signature verification must be performed before any business logic +- Secrets should be stored securely via environment variables +- Reject malformed or unsigned requests early + +Idempotency: +- Use the unique event identifier to prevent duplicate processing +- Store processed event IDs in a durable store (e.g., database table) +- Return success for duplicates to avoid retries + +Error handling: +- Log errors with context (event ID, type, user reference) +- Return non-2xx only when necessary; prefer 200 for successfully handled events +- Surface actionable errors for debugging + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Event Types and Payload Structures +Supported event types: +- payment.created +- payment.completed +- payment.failed + +Payload structure guidelines: +- Each event includes a unique event ID for idempotency +- Events include metadata linking to the customer and subscription +- Payment events contain payment details such as amount, currency, and status + +Processing expectations: +- For payment.created: acknowledge receipt and prepare fulfillment +- For payment.completed: activate or extend subscription access +- For payment.failed: mark subscription as failed and notify relevant systems + +Note: Refer to the PayMongo platform documentation for exact field names and formats. Ensure your handler is resilient to schema evolution by ignoring unknown fields. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Subscription Status Updates +Actions: +- On successful payment completion, update subscription status to active or renewed +- On payment failure, set subscription status to failed or expired +- Maintain audit logs for all status transitions + +Integration points: +- Entitlement manager updates user access rights based on subscription status +- Database persistence ensures consistency across reads and writes + +Idempotent updates: +- Use upsert patterns keyed by subscription ID +- Avoid double-charging or redundant activations + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Error Handling Strategies +Approach: +- Validate inputs and signatures first +- Catch and log exceptions with contextual information +- Return 200 for successfully processed events even if downstream updates fail, but record failures for later reconciliation +- Use structured logging for observability + +Retry behavior: +- Rely on PayMongo’s retry policy for transient failures +- Ensure your handler is idempotent so retries do not cause side effects + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Security Best Practices +- Signature validation: Always verify the webhook signature using the provided secret before processing +- Secret management: Store secrets in environment variables and never hardcode them +- IP whitelisting: If supported by your hosting environment, restrict inbound traffic to PayMongo IPs +- Input sanitization: Treat all incoming data as untrusted; validate and sanitize before use +- Least privilege: Limit database permissions to only what is required for webhook processing + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Idempotency Requirements +- Use the event ID to deduplicate requests +- Persist processed event IDs with timestamps +- Skip reprocessing if the same event ID is received again +- Ensure database constraints prevent duplicate entries where possible + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Retry Mechanisms +- Configure your runtime to handle transient network errors gracefully +- Let PayMongo manage retries for failed deliveries +- Keep handlers fast and idempotent to support retries without side effects + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Examples of Processing Different Webhook Events +- payment.created: Acknowledge and queue fulfillment tasks +- payment.completed: Activate subscription and grant entitlements +- payment.failed: Mark subscription as failed and trigger notifications + +Implementation notes: +- Branch logic by event type +- Perform minimal work per branch to reduce latency +- Record outcomes for auditing and debugging + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Updating Subscription Status +Flow: +- Map event outcome to desired subscription state +- Call entitlement manager to apply changes +- Persist state and return success + +Best practices: +- Use transactions to ensure consistency +- Include correlation IDs for tracing +- Handle partial failures with compensating actions + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Handling Payment Failures +Actions: +- Set subscription status to failed/expired +- Optionally pause services tied to paid features +- Notify users and support teams +- Schedule review or retry workflows as needed + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Conceptual Overview +```mermaid +flowchart TD +Start(["Receive Webhook"]) --> Parse["Parse JSON Body"] +Parse --> Verify["Verify Signature"] +Verify --> Valid{"Valid?"} +Valid --> |No| Reject["Return 401"] +Valid --> |Yes| Dedup["Check Idempotency"] +Dedup --> Seen{"Seen Before?"} +Seen --> |Yes| Success["Return 200"] +Seen --> |No| Dispatch["Dispatch by Event Type"] +Dispatch --> Completed{"payment.completed?"} +Completed --> |Yes| Activate["Activate Subscription"] +Completed --> |No| Failed{"payment.failed?"} +Failed --> |Yes| Deactivate["Mark Failed"] +Failed --> |No| Other["Handle Other Events"] +Activate --> Persist["Persist State"] +Deactivate --> Persist +Other --> Persist +Persist --> Success +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Dependency Analysis +The webhook handler depends on shared utilities for HTTP operations and entitlement management. Frontend billing logic may interact with the webhook indirectly via API calls. + +```mermaid +graph LR +WH["paymongo-webhook/index.ts"] --> ENT["_shared/entitlement.ts"] +WH --> HTTP["_shared/http.ts"] +BILL["lib/billing.js"] -. uses .-> WH +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [billing.js](file://src/lib/billing.js) + +## Performance Considerations +- Keep webhook handlers fast and stateless where possible +- Minimize database round-trips by batching updates +- Use indexes on frequently queried fields (e.g., event ID, subscription ID) +- Enable connection pooling for database access +- Monitor cold start times and optimize dependencies + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues: +- Signature verification failures: Check secret configuration and timestamp skew +- Duplicate processing: Ensure idempotency keys are persisted and checked +- Missing events: Inspect PayMongo dashboard for delivery status and retry attempts +- Slow responses: Profile handler execution and reduce I/O operations + +Debugging techniques: +- Log event IDs, types, and user references +- Capture request headers and payload summaries (sanitized) +- Correlate logs with PayMongo event IDs +- Use structured logging and centralized monitoring + +Operational tips: +- Implement health checks for the webhook endpoint +- Alert on high error rates or slow response times +- Periodically reconcile subscription states against payment records + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Conclusion +The PayMongo webhook handler integrates payment events into subscription and entitlement management with strong emphasis on security, idempotency, and reliability. By validating signatures, enforcing idempotency, and handling errors gracefully, the system ensures consistent state and robust operation. Follow the security best practices and troubleshooting guidance to maintain a healthy webhook pipeline. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayPal Order Management.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayPal Order Management.md new file mode 100644 index 0000000..6ae2076 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayPal Order Management.md @@ -0,0 +1,455 @@ +# PayPal Order Management + + +**Referenced Files in This Document** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the PayPal order management implementation for creating and capturing orders, including end-to-end workflows from order initiation to payment completion. It covers: +- The create-order endpoint for subscription details, pricing, and customer information +- The capture-order endpoint for finalizing payments and updating subscription status +- Error handling for declined payments, insufficient funds, and network timeouts +- Integration examples with retry logic and state synchronization between PayPal and application databases + +## Project Structure +The PayPal integration is implemented as Supabase Edge Functions with shared utilities and a database migration for fulfillment records. + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +CPO["create-paypal-order/index.ts"] +CAP["capture-paypal-order/index.ts"] +WEBHOOK["paypal-webhook/index.ts"] +SH_PAYPAL["_shared/paypal.ts"] +SH_RUNTIME["_shared/paypal-runtime.ts"] +SH_HTTP["_shared/http.ts"] +end +subgraph "Database" +MIG["migrations/002_paypal_fulfillment.sql"] +end +Client["Client App"] --> CPO +Client --> CAP +Client --> WEBHOOK +CPO --> SH_PAYPAL +CPO --> SH_RUNTIME +CPO --> SH_HTTP +CAP --> SH_PAYPAL +CAP --> SH_RUNTIME +CAP --> SH_HTTP +WEBHOOK --> SH_PAYPAL +WEBHOOK --> SH_RUNTIME +WEBHOOK --> SH_HTTP +CPO -.-> MIG +CAP -.-> MIG +WEBHOOK -.-> MIG +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypl-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Create Order Function: Accepts subscription plan, pricing, and customer context; calls PayPal to create an order and returns the approval URL. +- Capture Order Function: Finalizes a previously approved order, updates local fulfillment state, and activates subscriptions if applicable. +- Webhook Handler: Processes asynchronous PayPal events (e.g., payment completions) to reconcile state and activate subscriptions. +- Shared Utilities: + - PayPal client helpers for authentication and API calls + - HTTP transport abstraction for requests and retries + - Runtime configuration loader for secrets + +Key responsibilities: +- Input validation and normalization +- Idempotent operations where possible +- Robust error classification and user-facing messages +- State synchronization via fulfillment records + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Architecture Overview +End-to-end flow from order creation to payment completion and subscription activation. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CreateOrder as "create-paypal-order/index.ts" +participant PayPal as "PayPal API" +participant Capture as "capture-paypal-order/index.ts" +participant Webhook as "paypal-webhook/index.ts" +participant DB as "Fulfillment Records" +Client->>CreateOrder : "Create order request
subscription, pricing, customer" +CreateOrder->>PayPal : "Create Order" +PayPal-->>CreateOrder : "Order ID + approval link" +CreateOrder-->>Client : "Approval URL" +Note over Client,PayPal : "User approves on PayPal" +Client->>Capture : "Capture order by Order ID" +Capture->>PayPal : "Capture Order" +PayPal-->>Capture : "Payment captured" +Capture->>DB : "Record fulfillment success" +Capture-->>Client : "Success" +PayPal-->>Webhook : "Async event (payment completed)" +Webhook->>DB : "Reconcile and activate subscription" +Webhook-->>PayPal : "Acknowledge" +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Detailed Component Analysis + +### Create Order Endpoint +Purpose: +- Validate inputs for subscription plan, pricing, and customer data +- Build a PayPal order payload +- Call PayPal to create an order +- Return the approval URL to the client + +Request parameters: +- Subscription details: plan identifier, billing cycle, start date +- Pricing: currency, amount, tax/shipping breakdown if applicable +- Customer information: email, name, optional shipping address +- Contextual metadata: internal order reference, callback URLs + +Processing logic: +- Normalize and validate input fields +- Construct PayPal order body with items and purchase units +- Invoke PayPal create order via shared utilities +- Persist a pending fulfillment record for idempotency and auditability +- Return approval URL and order reference + +Error handling: +- Invalid or missing fields return clear validation errors +- Network failures are retried with backoff +- PayPal business errors are mapped to user-friendly messages + +Integration notes: +- Use idempotency keys when available +- Store minimal PII locally; rely on PayPal for sensitive data + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +#### Create Order Flowchart +```mermaid +flowchart TD +Start(["Function Entry"]) --> Validate["Validate inputs
subscription, pricing, customer"] +Validate --> Valid{"Valid?"} +Valid --> |No| ErrInvalid["Return validation error"] +Valid --> |Yes| BuildPayload["Build PayPal order payload"] +BuildPayload --> CallAPI["Call PayPal Create Order"] +CallAPI --> APIOK{"API OK?"} +APIOK --> |No| RetryCheck["Retry with backoff?"] +RetryCheck --> |Yes| CallAPI +RetryCheck --> |No| ErrNetwork["Return network/business error"] +APIOK --> |Yes| Persist["Persist pending fulfillment"] +Persist --> ReturnURL["Return approval URL"] +ReturnURL --> End(["Function Exit"]) +ErrInvalid --> End +ErrNetwork --> End +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Capture Order Endpoint +Purpose: +- Finalize a previously approved PayPal order +- Update fulfillment status to paid +- Activate subscription entitlements + +Request parameters: +- Order ID (from create-order response) +- Optional authorization token if required by your flow +- Internal identifiers for linking to user accounts and plans + +Processing logic: +- Validate presence of Order ID +- Call PayPal capture using shared utilities +- On success, update fulfillment records and activate subscription +- On failure, classify error and return actionable message + +Error handling: +- Declined payment: inform user and allow retry with updated payment method +- Insufficient funds: prompt re-authentication or alternative payment +- Network timeout: retry with exponential backoff and circuit breaker hints + +Idempotency: +- Ensure repeated captures do not double-charge +- Record capture attempts and outcomes + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +#### Capture Order Sequence +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Capture as "capture-paypal-order/index.ts" +participant PayPal as "PayPal API" +participant DB as "Fulfillment Records" +Client->>Capture : "Capture by Order ID" +Capture->>PayPal : "Capture Order" +PayPal-->>Capture : "Captured or error" +alt Success +Capture->>DB : "Mark fulfilled and activate subscription" +Capture-->>Client : "Success" +else Failure +Capture-->>Client : "Declined/Insufficient funds/Timeout" +end +``` + +**Diagram sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +### PayPal Webhook Handler +Purpose: +- Receive asynchronous PayPal events (e.g., payment completed) +- Reconcile order state and ensure subscription activation even if capture fails +- Maintain consistent state across systems + +Processing logic: +- Verify webhook signature and source +- Parse event type and payload +- Match event to existing fulfillment records +- Update status and trigger subscription activation +- Acknowledge receipt to PayPal + +Error handling: +- Reject unknown or malformed events +- Log and surface verification failures +- Implement idempotent processing to avoid duplicate activations + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +#### Webhook Processing Flow +```mermaid +flowchart TD +WStart(["Webhook Received"]) --> Verify["Verify signature and source"] +Verify --> Verified{"Verified?"} +Verified --> |No| Reject["Reject and log"] +Verified --> |Yes| Parse["Parse event type and payload"] +Parse --> Match["Match to fulfillment record"] +Match --> Found{"Found?"} +Found --> |No| Unknown["Log unknown event"] +Found --> |Yes| Update["Update fulfillment and activate subscription"] +Update --> Ack["Acknowledge to PayPal"] +Ack --> WEnd(["Done"]) +Reject --> WEnd +Unknown --> WEnd +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Shared Utilities + +#### PayPal Client Helpers +Responsibilities: +- Authenticate with PayPal using runtime-configured credentials +- Build and send REST API requests for order lifecycle operations +- Map PayPal error codes to domain-specific messages + +Complexity considerations: +- Minimize token refresh overhead by caching tokens within function lifetime +- Use connection pooling via HTTP client + +**Section sources** +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +#### HTTP Transport Abstraction +Responsibilities: +- Provide standardized request/response handling +- Implement retry with exponential backoff and jitter +- Enforce timeouts and circuit breaker hints for resilience + +Error classification: +- Network errors vs. server errors vs. client errors +- Distinguish transient vs. permanent failures + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Database Schema for Fulfillment +The migration defines tables and indexes necessary to track order fulfillment, capture attempts, and subscription activation. Typical fields include: +- Unique order reference +- Status transitions (pending, captured, failed) +- Timestamps for auditing +- Links to user accounts and subscription plans + +Ensure: +- Unique constraints to prevent duplicates +- Indexes on frequently queried columns (order_id, user_id, status) +- Audit trails for compliance + +**Section sources** +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +Internal dependencies: +- create-paypal-order depends on shared PayPal client, HTTP transport, and runtime config +- capture-paypal-order depends on shared PayPal client, HTTP transport, and runtime config +- paypal-webhook depends on shared PayPal client, HTTP transport, and runtime config +- All functions may interact with fulfillment records defined in the migration + +External dependencies: +- PayPal REST APIs for order creation and capture +- Supabase Edge runtime for environment variables and execution context + +```mermaid +graph LR +CPO["create-paypal-order/index.ts"] --> SHP["_shared/paypal.ts"] +CPO --> SHR["_shared/paypal-runtime.ts"] +CPO --> SHH["_shared/http.ts"] +CAP["capture-paypal-order/index.ts"] --> SHP +CAP --> SHR +CAP --> SHH +WEB["paypal-webhook/index.ts"] --> SHP +WEB --> SHR +WEB --> SHH +MIG["002_paypal_fulfillment.sql"] -.-> CPO +MIG -.-> CAP +MIG -.-> WEB +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Token caching: reuse PayPal access tokens within function lifetime to reduce latency +- Connection reuse: leverage HTTP client pooling for outbound calls +- Idempotency: use unique order references to prevent duplicate charges +- Backoff and jitter: implement exponential backoff with randomization for retries +- Timeouts: set reasonable request timeouts to fail fast under load +- Minimal payloads: pass only necessary fields to reduce bandwidth and parsing time + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Declined payments: + - Check PayPal error code and message + - Prompt user to update payment method and retry capture + - Log attempt with correlation IDs for support +- Insufficient funds: + - Inform user and suggest alternative funding source + - Allow retry after user updates payment method +- Network timeouts: + - Enable retries with exponential backoff + - Monitor upstream service health and circuit breaker metrics +- Signature verification failures: + - Validate webhook secret and timestamp tolerance + - Reject and log suspicious events + +Operational tips: +- Correlate logs using order IDs and webhook event IDs +- Track fulfillment state transitions for auditability +- Alert on high failure rates or repeated declines + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +The PayPal order management implementation provides a robust, resilient workflow for creating orders, capturing payments, and synchronizing state through webhooks. By leveraging shared utilities for authentication, HTTP transport, and runtime configuration, the system ensures consistency, idempotency, and clear error handling. Proper integration patterns—such as retry logic, state reconciliation, and comprehensive logging—help maintain reliability and a smooth user experience. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Integration Examples + +- Creating an order: + - Collect subscription plan, pricing, and customer info + - Call create-order endpoint + - Redirect user to approval URL + - On return, proceed to capture + +- Capturing an order: + - Send Order ID to capture endpoint + - Handle success and failure responses + - Update UI and notify user + +- Handling webhooks: + - Verify signature and parse event + - Match to fulfillment record + - Activate subscription and acknowledge + +- Error handling and retries: + - Classify errors (declined, insufficient funds, timeout) + - Apply retry with backoff for transient failures + - Surface actionable messages to users + +- State synchronization: + - Persist fulfillment records at each step + - Reconcile via webhooks to ensure eventual consistency + - Provide admin tools to inspect and repair state + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayPal Webhook Handler.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayPal Webhook Handler.md new file mode 100644 index 0000000..5274d8d --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/PayPal Webhook Handler.md @@ -0,0 +1,415 @@ +# PayPal Webhook Handler + + +**Referenced Files in This Document** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive webhook documentation for PayPal payment events within the project. It covers supported event types, payload schemas, verification processes using PayPal’s certificate-based authentication, event processing workflows, subscription lifecycle management, billing agreement updates, and security considerations. It also includes monitoring and alerting strategies for webhook processing failures. + +## Project Structure +The PayPal integration is implemented as Supabase Edge Functions with shared utilities and database migrations: +- Webhook handler function receives and verifies PayPal events +- Shared PayPal client and runtime helpers encapsulate API calls and configuration +- Database schema defines tables for order fulfillment and subscription state +- Additional functions orchestrate order creation, capture, and subscription cancellation + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +WH["paypal-webhook/index.ts"] +PO["create-paypal-order/index.ts"] +CO["capture-paypal-order/index.ts"] +CS["cancel-subscription/index.ts"] +end +subgraph "Shared Utilities" +PP["paypal.ts"] +PR["paypal-runtime.ts"] +end +subgraph "Database" +DB["002_paypal_fulfillment.sql"] +end +WH --> PP +WH --> PR +PO --> PP +CO --> PP +CS --> PP +WH --> DB +PO --> DB +CO --> DB +CS --> DB +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Core Components +- Webhook handler: Receives HTTP requests from PayPal, validates headers and signature, decodes payloads, and dispatches to event-specific processors. +- PayPal client: Encapsulates REST API interactions (orders, subscriptions, billing agreements), token retrieval, and error mapping. +- Runtime helpers: Provide environment configuration, logging, and common utilities used by all PayPal-related functions. +- Database schema: Defines tables for orders, subscriptions, and fulfillment records to persist state changes. + +Key responsibilities: +- Verify webhook authenticity via PayPal’s certificate chain and request headers +- Idempotently process events using event IDs +- Update subscription status and billing agreement metadata +- Record fulfillment outcomes and audit logs + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +The system follows a clear separation between inbound webhook handling, PayPal API interactions, and persistent state management. + +```mermaid +sequenceDiagram +participant Client as "PayPal" +participant Func as "paypal-webhook/index.ts" +participant Util as "paypal.ts" +participant RT as "paypal-runtime.ts" +participant DB as "DB Schema" +Client->>Func : "HTTP POST /paypal-webhook" +Func->>RT : "Load config and logger" +Func->>Func : "Validate headers and signature" +Func->>Util : "Decode and normalize payload" +Util-->>Func : "Normalized event object" +Func->>DB : "Upsert fulfillment record (idempotent)" +alt "Payment completed" +Func->>DB : "Update order/subscriptions" +else "Subscription cancelled" +Func->>DB : "Mark subscription inactive" +end +Func-->>Client : "200 OK" +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Webhook Handler +Responsibilities: +- Accepts PayPal webhook requests +- Validates request headers and signature using PayPal’s certificate chain +- Decodes and normalizes payloads into internal event models +- Dispatches to event-specific handlers +- Persists idempotent records to prevent duplicate processing +- Returns appropriate HTTP responses + +Supported event types: +- PAYMENT.SALE.COMPLETED +- BILLING.SUBSCRIPTION.CANCELLED +- BILLING.SUBSCRIPTION.ACTIVATED +- BILLING.SUBSCRIPTION.UPDATED +- BILLING.SUBSCRIPTION.EXPIRED +- BILLING.SUBSCRIPTION.PAYMENT.FAILED +- BILLING.SUBSCRIPTION.RE-AUTHORIZED +- BILLING.SUBSCRIPTION.SUSPENDED +- BILLING.SUBSCRIPTION.CANCELLED (alias if present) +- BILLING.AGREEMENT.CREATED +- BILLING.AGREEMENT.UPDATED +- BILLING.AGREEMENT.EXPIRED +- ORDERS.APPROVED +- ORDERS.CAPTURED +- ORDERS.DENIED +- ORDERS.REFUNDED + +Payload schema highlights: +- Event ID and type for idempotency and routing +- Resource object containing transaction details, payer info, and subscription metadata +- Timestamps for ordering and processing +- Links for resource retrieval and related operations + +Verification process: +- Validate required headers (e.g., transmission ID, certification URL, webhook ID) +- Fetch PayPal’s certificate chain using the provided certification URL +- Verify the webhook signature against the raw request body +- Ensure webhook ID matches configured endpoint + +Event processing workflow: +- Normalize payload into internal model +- Check existing fulfillment record for idempotency +- Apply business rules per event type +- Update subscription or order state accordingly +- Log outcome and metrics + +```mermaid +flowchart TD +Start(["Incoming Webhook"]) --> ValidateHeaders["Validate Headers and Signature"] +ValidateHeaders --> Valid{"Valid?"} +Valid --> |No| Reject["Return 401/400"] +Valid --> |Yes| Decode["Decode Payload"] +Decode --> Normalize["Normalize to Internal Model"] +Normalize --> Idempotent["Check Existing Fulfillment Record"] +Idempotent --> Exists{"Exists?"} +Exists --> |Yes| ReturnOK["Return 200 OK (no-op)"] +Exists --> |No| Route["Route by Event Type"] +Route --> Process["Apply Business Rules"] +Process --> Persist["Persist State Changes"] +Persist --> ReturnOK +Reject --> End(["End"]) +ReturnOK --> End +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### PayPal Client and Runtime +Responsibilities: +- Manage OAuth tokens and API base URLs +- Execute REST calls for orders, subscriptions, and billing agreements +- Map PayPal errors to application-level exceptions +- Provide consistent logging and retry behavior + +Key capabilities: +- Token acquisition and caching +- Request signing and header injection +- Response normalization and error translation +- Environment-aware configuration (sandbox vs production) + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +### Subscription Lifecycle Management +Lifecycle states: +- Created +- Activated +- Suspended +- Expired +- Cancelled +- Re-authorized + +Processing logic: +- On ACTIVATED: Enable entitlements and update billing agreement metadata +- On UPDATED: Sync plan changes, proration, and next billing date +- On CANCELLED/SUSPENDED/EXPIRED: Disable entitlements and mark subscription inactive +- On RE-AUTHORIZED: Refresh authorization and resume billing + +Billing agreement updates: +- Maintain external agreement ID and last updated timestamp +- Store payer consent and shipping preferences when available +- Track plan identifiers and effective dates + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Order Processing and Capture +Order flow: +- Create order via create-paypal-order function +- Approve order on frontend +- Capture funds via capture-paypal-order function +- Fulfill upon successful capture + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant COF as "create-paypal-order/index.ts" +participant CF as "capture-paypal-order/index.ts" +participant PP as "paypal.ts" +participant DB as "DB Schema" +FE->>COF : "Create order" +COF->>PP : "Create order via API" +PP-->>COF : "Order ID and links" +COF-->>FE : "Order ID" +FE->>CF : "Capture order" +CF->>PP : "Capture order via API" +PP-->>CF : "Capture result" +CF->>DB : "Record fulfillment" +CF-->>FE : "Success" +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Subscription Cancellation Flow +Cancellation triggers: +- User-initiated via cancel-subscription function +- PayPal-initiated via BILLING.SUBSCRIPTION.CANCELLED webhook + +```mermaid +sequenceDiagram +participant Admin as "Admin UI" +participant CSF as "cancel-subscription/index.ts" +participant PP as "paypal.ts" +participant DB as "DB Schema" +Admin->>CSF : "Cancel subscription" +CSF->>PP : "Cancel subscription via API" +PP-->>CSF : "Cancellation result" +CSF->>DB : "Mark subscription inactive" +CSF-->>Admin : "Success" +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +The following diagram shows how components depend on each other: + +```mermaid +graph LR +WH["paypal-webhook/index.ts"] --> PP["paypal.ts"] +WH --> PR["paypal-runtime.ts"] +PO["create-paypal-order/index.ts"] --> PP +CO["capture-paypal-order/index.ts"] --> PP +CS["cancel-subscription/index.ts"] --> PP +WH --> DB["002_paypal_fulfillment.sql"] +PO --> DB +CO --> DB +CS --> DB +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Performance Considerations +- Idempotency: Use event IDs to avoid duplicate processing and ensure safe retries. +- Minimal I/O: Perform only necessary database writes; batch updates where possible. +- Logging: Keep structured logs with correlation IDs for tracing. +- Timeouts: Configure appropriate timeouts for outbound PayPal API calls. +- Backpressure: Queue long-running tasks if needed to keep webhook response times low. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid signature: Verify webhook ID, transmission ID, and certification URL; ensure raw body is preserved during verification. +- Missing headers: Confirm PayPal sends required headers; log missing fields for diagnostics. +- Duplicate events: Check fulfillment records by event ID; return success without reprocessing. +- Subscription state mismatch: Compare PayPal state with local state; reconcile discrepancies via reconciliation jobs. +- Network errors: Implement retries with exponential backoff for transient failures. + +Monitoring and alerting strategies: +- Track webhook latency and error rates +- Alert on signature validation failures +- Monitor subscription state drift between PayPal and local DB +- Set up dashboards for fulfillment success/failure ratios + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Conclusion +The PayPal webhook implementation provides secure, idempotent processing of payment and subscription events. By leveraging certificate-based verification, normalized payloads, and robust state management, the system ensures reliable fulfillment and accurate subscription lifecycle handling. Monitoring and alerting further enhance operational visibility and resilience. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Security Considerations +- Webhook URL configuration: + - Register the correct HTTPS endpoint in PayPal dashboard + - Use environment-specific endpoints for sandbox and production +- Certificate validation: + - Always fetch certificates from PayPal-provided URLs + - Validate signatures against the raw request body +- Secure environment setup: + - Store secrets securely in environment variables + - Restrict access to webhook endpoints and admin functions + - Enable TLS and enforce strong cipher suites + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +### Example Scenarios +- Recurring payments: + - Handle BILLING.SUBSCRIPTION.PAYMENT.SUCCESSFUL events to continue entitlements + - Update next billing date and track payment history +- Subscription upgrades/downgrades: + - Process BILLING.SUBSCRIPTION.UPDATED events + - Apply proration and adjust plan identifiers +- Cancellations: + - Respond to BILLING.SUBSCRIPTION.CANCELLED by disabling entitlements + - Honor grace periods and refund policies as applicable + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Subscription Cancellation Service.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Subscription Cancellation Service.md new file mode 100644 index 0000000..13eb729 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Billing & Payment Functions/Subscription Cancellation Service.md @@ -0,0 +1,408 @@ +# Subscription Cancellation Service + + +**Referenced Files in This Document** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document specifies the subscription cancellation service, focusing on the cancellation endpoint and its integration with external payment providers (PayPal and PayMongo). It covers authentication requirements, request parameters, response formats, business rules (eligibility, prorated refunds, access revocation timing), workflow examples (immediate vs end-of-period cancellations), refund handling, data retention policies, and integration patterns for updating local subscription status after provider confirmation. + +## Project Structure +The cancellation flow spans serverless functions, shared provider utilities, webhooks, and client-side billing logic: +- Serverless function: cancel-subscription +- Shared provider utilities: PayPal client helpers +- Webhooks: PayPal and PayMongo event handlers +- Client libraries: billing and entitlement modules +- Documentation: architecture and monetization plans + +```mermaid +graph TB +Client["Client App"] --> API["Cancel Subscription Function
supabase/functions/cancel-subscription/index.ts"] +API --> PayPal["PayPal Provider
supabase/functions/_shared/paypal.ts"] +API --> DB["Supabase Database"] +PayPal --> PayPalAPI["PayPal External API"] +PayMongoWebhook["PayMongo Webhook
supabase/functions/paymongo-webhook/index.ts"] --> DB +PayPalWebhook["PayPal Webhook
supabase/functions/paypal-webhook/index.ts"] --> DB +Client --> Billing["Billing Library
src/lib/billing.js"] +Client --> Entitlement["Entitlement Library
src/lib/entitlement.js"] +DB --> Entitlement +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Cancel Subscription Function: Orchestrates cancellation by validating inputs, enforcing business rules, invoking provider APIs, and persisting state changes. +- PayPal Integration: Provides helper methods to call PayPal’s subscription management endpoints. +- Webhooks: Receive asynchronous confirmations from providers to reconcile final states and update local records. +- Client Libraries: Expose high-level billing operations and entitlement checks used by the UI. + +Key responsibilities: +- Validate user identity and authorization +- Resolve subscription and plan details +- Determine cancellation type (immediate vs end-of-period) +- Compute refund eligibility and proration +- Call provider APIs to schedule or execute cancellation +- Persist audit logs and updated subscription status +- Emit events for downstream sync and entitlement updates + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +## Architecture Overview +High-level cancellation flow: +- Client calls the cancel-subscription function with required parameters. +- Function validates authentication and subscription ownership. +- Function determines cancellation policy (immediate vs end-of-period) and computes refund/proration. +- Function invokes provider APIs (PayPal/PayMongo) to schedule or finalize cancellation. +- Provider responds with confirmation; function persists state and returns a structured response. +- Webhooks may later reconcile final outcomes and update entitlements. + +```mermaid +sequenceDiagram +participant Client as "Client" +participant Func as "Cancel Subscription Function" +participant Provider as "Payment Provider" +participant DB as "Database" +participant Ent as "Entitlement Service" +Client->>Func : "POST /cancel-subscription {subscriptionId, reason}" +Func->>DB : "Load subscription and plan" +Func->>Func : "Validate auth and eligibility" +Func->>Provider : "Schedule/Finalize cancellation" +Provider-->>Func : "Cancellation result" +Func->>DB : "Persist cancellation record and status" +Func-->>Client : "Response {status, effectiveDate, refundAmount}" +Note over Func,Ent : "On success, trigger entitlement update" +Provider-->>Func : "Webhook (if async)" +Func->>DB : "Reconcile final state" +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +## Detailed Component Analysis + +### Cancellation Endpoint Specification +- Method: POST +- Path: /functions/v1/cancel-subscription +- Authentication: Required (user session token) +- Request body: + - subscriptionId: string, required + - reason: string, required +- Response formats: + - Success (immediate): + - status: "cancelled" + - effectiveDate: ISO timestamp + - refundAmount: number or null + - message: string + - Pending (end-of-period): + - status: "pending_cancellation" + - effectiveDate: ISO timestamp (period end) + - refundAmount: number or null + - message: string + - Error: + - status: "error" + - code: string + - message: string + +Business rules: +- Eligibility: + - Subscription must be active or in grace period per plan rules. + - Ownership verified via authenticated user context. +- Cancellation types: + - Immediate: cancels now; refund computed if eligible. + - End-of-period: schedules cancellation at next billing cycle; partial refund may apply based on proration policy. +- Prorated refunds: + - Calculated based on remaining days in current period minus non-refundable fees. + - If provider supports proration, use provider calculation; otherwise compute locally using plan terms. +- Access revocation timing: + - Immediate: revoke access immediately upon successful cancellation. + - End-of-period: maintain access until effectiveDate; revoke at that time. +- Data retention: + - Retain cancellation audit records indefinitely for compliance. + - Personal data follows platform retention policy; anonymize where applicable. + +Integration notes: +- For PayPal, use provider helpers to schedule/finalize cancellation and capture confirmation. +- For PayMongo, rely on webhook-driven reconciliation to finalize state. + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +### Workflow Examples + +#### Immediate Cancellation +- Trigger: User requests immediate cancellation. +- Steps: + - Validate auth and subscription ownership. + - Check eligibility and compute refund. + - Call provider to cancel immediately. + - Persist cancellation and revoke access. + - Return success response with effectiveDate equal to now. + +```mermaid +flowchart TD +Start(["Start"]) --> Auth["Authenticate and authorize"] +Auth --> Load["Load subscription and plan"] +Load --> Eligible{"Eligible for immediate?"} +Eligible --> |No| Error["Return error with code/message"] +Eligible --> |Yes| Refund["Compute refund amount"] +Refund --> ProviderCall["Call provider to cancel immediately"] +ProviderCall --> Persist["Persist cancellation record"] +Persist --> Revoke["Revoke access immediately"] +Revoke --> Respond["Return success response"] +Error --> End(["End"]) +Respond --> End +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +#### End-of-Period Cancellation +- Trigger: User requests cancellation at period end. +- Steps: + - Validate auth and subscription ownership. + - Determine effectiveDate as next billing cycle end. + - Schedule cancellation with provider. + - Persist pending cancellation and keep access until effectiveDate. + - Return pending response with effectiveDate. + +```mermaid +flowchart TD +Start(["Start"]) --> Auth["Authenticate and authorize"] +Auth --> Load["Load subscription and plan"] +Load --> Effective["Calculate effectiveDate (period end)"] +Effective --> Schedule["Schedule cancellation with provider"] +Schedule --> Persist["Persist pending cancellation"] +Persist --> KeepAccess["Keep access until effectiveDate"] +KeepAccess --> Respond["Return pending response"] +Respond --> End(["End"]) +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +#### Refund Handling +- Immediate cancellation: + - If eligible, compute prorated refund and initiate refund via provider. + - On provider confirmation, persist refund amount and update records. +- End-of-period cancellation: + - If proration applies, calculate partial refund based on remaining days. + - Initiate refund at period end or when provider allows. + +```mermaid +flowchart TD +Start(["Start"]) --> Type{"Cancellation type"} +Type --> |Immediate| CalcImm["Compute immediate refund"] +Type --> |End-of-period| CalcEOP["Compute prorated refund"] +CalcImm --> InitRefund["Initiate refund via provider"] +CalcEOP --> InitRefund +InitRefund --> Confirm{"Provider confirmed?"} +Confirm --> |Yes| PersistRefund["Persist refund amount"] +Confirm --> |No| Retry["Retry or escalate"] +PersistRefund --> Done(["Done"]) +Retry --> Done +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +#### Data Retention Policies +- Audit logs: + - Store cancellation requests, provider responses, and outcome decisions. +- Personal data: + - Follow platform policy; anonymize identifiers where feasible. +- Compliance: + - Maintain records for auditability and dispute resolution. + +[No sources needed since this section provides general guidance] + +### Business Rules Summary +- Eligibility: + - Active or grace-period subscriptions only. + - Must be owned by authenticated user. +- Prorated refunds: + - Based on remaining days minus non-refundable fees. + - Use provider calculation when available; fallback to local computation. +- Access revocation: + - Immediate: revoke now. + - End-of-period: revoke at effectiveDate. + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +### Integration with External Payment Providers +- PayPal: + - Use provider helpers to schedule/finalize cancellation and handle confirmations. + - Webhook handler reconciles final state and updates local records. +- PayMongo: + - Rely on webhook-driven reconciliation to finalize state and update entitlements. + +```mermaid +sequenceDiagram +participant Func as "Cancel Subscription Function" +participant PayPal as "PayPal Helper" +participant PayPalWH as "PayPal Webhook" +participant PayMongoWH as "PayMongo Webhook" +participant DB as "Database" +Func->>PayPal : "Schedule/Finalize cancellation" +PayPal-->>Func : "Confirmation" +Func->>DB : "Update subscription status" +PayPalWH->>DB : "Reconcile final state" +PayMongoWH->>DB : "Reconcile final state" +``` + +**Diagram sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +### Client-Side Integration +- Billing library: + - Exposes high-level methods to initiate cancellation and poll for status. +- Entitlement library: + - Checks current entitlements and enforces feature access based on subscription state. + +Usage pattern: +- Call billing method with subscriptionId and reason. +- Handle response: + - Immediate success: revoke features immediately. + - Pending: continue access until effectiveDate. +- Listen for webhook-driven updates to refresh entitlements. + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +## Dependency Analysis +- The cancellation function depends on: + - Provider utilities (PayPal) + - Database for persistence + - Webhooks for reconciliation +- Client libraries depend on: + - Billing module for API calls + - Entitlement module for access control + +```mermaid +graph TB +Cancel["cancel-subscription/index.ts"] --> PayPal["paypal.ts"] +Cancel --> DB["Database"] +PayPal --> PayPalAPI["PayPal External API"] +PayPalWH["paypal-webhook/index.ts"] --> DB +PayMongoWH["paymongo-webhook/index.ts"] --> DB +Billing["billing.js"] --> Cancel +Entitlement["entitlement.js"] --> DB +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Performance Considerations +- Minimize provider round-trips by batching validation and scheduling steps. +- Cache plan and pricing metadata to reduce database reads during cancellation. +- Use idempotency keys for cancellation requests to prevent duplicate processing. +- Implement retries with exponential backoff for transient provider errors. +- Ensure webhook handlers are idempotent and fast to avoid backlog. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid or missing subscriptionId: + - Verify existence and ownership before proceeding. +- Unauthorized access: + - Ensure user session is valid and matches subscription owner. +- Provider errors: + - Log provider error codes and messages; retry with backoff; escalate on persistent failures. +- State mismatch between provider and local records: + - Use webhooks to reconcile; implement conflict resolution strategies. +- Refund discrepancies: + - Compare provider-calculated amounts with local computations; adjust proration logic accordingly. + +Operational tips: +- Enable detailed logging for all cancellation attempts and provider interactions. +- Monitor webhook delivery and processing latency. +- Set up alerts for failed cancellations and refund anomalies. + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Conclusion +The subscription cancellation service provides a robust, auditable pathway to cancel subscriptions either immediately or at period end, with clear business rules for eligibility, proration, and access revocation. Integration with PayPal and PayMongo ensures reliable provider coordination and reconciliation through webhooks. Clients can confidently manage cancellation flows using the billing and entitlement libraries while maintaining compliance through comprehensive data retention practices. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### API Reference Summary +- Endpoint: POST /functions/v1/cancel-subscription +- Authentication: Required +- Request parameters: + - subscriptionId: string + - reason: string +- Responses: + - Success (immediate): { status: "cancelled", effectiveDate, refundAmount, message } + - Pending (end-of-period): { status: "pending_cancellation", effectiveDate, refundAmount, message } + - Error: { status: "error", code, message } + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Data Export & Utilities.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Data Export & Utilities.md new file mode 100644 index 0000000..38daf43 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Data Export & Utilities.md @@ -0,0 +1,330 @@ +# Data Export & Utilities + + +**Referenced Files in This Document** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides detailed API documentation for data export and utility Edge Functions, with a focus on the message pack download function. It covers HTTP methods, URL patterns, authentication requirements, response formats, serialization patterns, file size limitations, performance considerations for large datasets, and client implementation examples for triggering exports, handling download progress, and managing file storage. It also documents the shared HTTP utilities library and common request/response helpers used across edge functions. + +## Project Structure +The relevant code is organized under Supabase Edge Functions: +- Shared utilities are located in supabase/functions/_shared. +- Feature-specific endpoints are each implemented as their own function directory under supabase/functions. + +```mermaid +graph TB +subgraph "Edge Functions" +A["download-message-pack/index.ts"] +B["_shared/http.ts"] +C["_shared/entitlement.ts"] +D["_shared/paypal-runtime.ts"] +E["ai-proxy/index.ts"] +F["cancel-subscription/index.ts"] +G["capture-paypal-order/index.ts"] +H["create-checkout/index.ts"] +I["create-paypal-order/index.ts"] +J["paymongo-webhook/index.ts"] +K["paypal-webhook/index.ts"] +end +A --> B +A --> C +E --> B +F --> B +G --> B +H --> B +I --> B +J --> B +K --> B +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Core Components +- Message Pack Download Function: Generates a serialized payload (MessagePack), compresses it, and serves a secure downloadable file. +- Shared HTTP Utilities: Provides standardized request parsing, response helpers, error formatting, and optional compression/streaming support. +- Entitlements: Validates user permissions or subscription status before allowing export operations. +- Payment Webhooks and Checkout Helpers: Demonstrate consistent request validation, signature verification, and structured responses. + +Key responsibilities: +- Enforce authentication and authorization checks prior to generating exports. +- Serialize application data into MessagePack for compact representation. +- Compress output using gzip to reduce bandwidth. +- Stream responses when necessary to handle large payloads efficiently. +- Return well-formed JSON errors for non-successful outcomes. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview +The message pack download flow integrates authentication, entitlement checks, data serialization, compression, and streaming delivery. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "download-message-pack/index.ts" +participant Http as "_shared/http.ts" +participant Ent as "_shared/entitlement.ts" +Client->>Edge : "GET /functions/v1/download-message-pack" +Edge->>Http : "parseRequest(request)" +Http-->>Edge : "parsed headers/body" +Edge->>Ent : "checkEntitlement(user)" +Ent-->>Edge : "ok | deny" +Edge->>Edge : "serialize data to MessagePack" +Edge->>Edge : "compress with gzip" +Edge->>Http : "streamResponse({headers, body})" +Http-->>Client : "application/octet-stream (gzip)" +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Message Pack Download API +- Purpose: Generate and serve a compressed MessagePack export file securely. +- Method: GET +- URL Pattern: /functions/v1/download-message-pack +- Authentication: Requires valid session token; validated via shared utilities. +- Authorization: Entitlement check enforced before export generation. +- Request Headers: + - Authorization: Bearer + - Optional query parameters may control export scope (implementation-dependent). +- Response: + - Success: application/octet-stream with Content-Encoding: gzip and appropriate Content-Disposition for download. + - Error: application/json with structured error object. + +Data Serialization and Compression: +- Data is serialized using MessagePack for compact binary format. +- Output is gzip-compressed to minimize transfer size. +- Streaming is preferred for large datasets to avoid memory spikes. + +File Size Limitations: +- Enforce maximum payload size at the function level to prevent abuse. +- Reject oversized requests early with a clear error. + +Security Considerations: +- Validate user identity and entitlements before exporting. +- Avoid logging sensitive data. +- Use HTTPS-only transport. + +Client Implementation Examples: +- Trigger export by calling the endpoint with proper Authorization header. +- Handle binary response and save to local storage or device filesystem. +- For large files, implement chunked download and resume capability if supported by the server. + +Progress Handling: +- If the server supports range requests or SSE, clients can track progress accordingly. +- Otherwise, rely on standard download progress events provided by the runtime. + +Storage Management: +- Save exported files with deterministic names and metadata. +- Implement cleanup policies for old exports. + +Error Handling: +- Parse JSON error responses and surface actionable messages to users. +- Retry transient failures with exponential backoff. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Shared HTTP Utilities Library +Responsibilities: +- Parse incoming requests safely and consistently. +- Provide helper functions to construct successful and error responses. +- Support streaming responses for large payloads. +- Centralize content-type and encoding handling. +- Normalize error shapes across all edge functions. + +Common Patterns: +- Use typed request parsing to extract headers, query params, and body. +- Wrap business logic calls with try/catch to return standardized JSON errors. +- Apply compression only when beneficial and supported by the client. + +Usage Across Edge Functions: +- All feature functions import and use these helpers to ensure consistent behavior. + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Entitlements Helper +Responsibilities: +- Verify user eligibility for protected features such as exports. +- Integrate with subscription or account state. +- Return structured results indicating allow/deny decisions. + +Integration Points: +- Called by export endpoints prior to data processing. +- Used by other protected endpoints to gate access. + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Payment Runtime Utilities +Responsibilities: +- Provide helpers for PayPal order creation, capture, and webhook processing. +- Standardize request validation and response formatting. +- Demonstrate robust error handling and idempotency patterns. + +Relevance: +- Illustrates consistent patterns that also apply to export endpoints. + +**Section sources** +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Dependency Analysis +The following diagram shows how the message pack download function depends on shared utilities and entitlement checks, and how other functions reuse the same HTTP helpers. + +```mermaid +graph LR +DM["download-message-pack/index.ts"] --> SH["http.ts"] +DM --> ENT["entitlement.ts"] +AP["ai-proxy/index.ts"] --> SH +CS["cancel-subscription/index.ts"] --> SH +CP["capture-paypal-order/index.ts"] --> SH +CC["create-checkout/index.ts"] --> SH +CPO["create-paypal-order/index.ts"] --> SH +PW["paymongo-webhook/index.ts"] --> SH +PPW["paypal-webhook/index.ts"] --> SH +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Performance Considerations +- Prefer streaming responses for large exports to reduce memory usage and time-to-first-byte. +- Enable gzip compression for binary payloads to minimize bandwidth. +- Validate and reject oversized requests early to protect resources. +- Batch data retrieval and avoid N+1 queries where possible. +- Cache frequently accessed reference data to reduce database load. +- Monitor function execution duration and memory footprint; adjust batch sizes accordingly. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: Ensure Authorization header contains a valid session token. +- Entitlement denied: Confirm user has required subscription or permission. +- Payload too large: Reduce export scope or split into multiple smaller exports. +- Compression errors: Verify client supports gzip decoding. +- Network timeouts: Implement retries with backoff and consider resumable downloads. + +Operational tips: +- Log structured errors without sensitive data. +- Surface user-friendly messages from JSON error responses. +- Inspect response headers for content type and encoding. + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) + +## Conclusion +The message pack download Edge Function demonstrates a secure, efficient pattern for exporting large datasets using MessagePack serialization and gzip compression. The shared HTTP utilities provide consistent request/response handling across all functions, while entitlement checks enforce access control. By following the recommended client patterns and performance practices, applications can reliably trigger exports, manage progress, and store files effectively. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### API Reference Summary +- Endpoint: GET /functions/v1/download-message-pack +- Authentication: Required (Bearer token) +- Authorization: Entitlement check enforced +- Request Headers: + - Authorization: Bearer +- Response: + - 200 OK: application/octet-stream (Content-Encoding: gzip) + - 4xx/5xx: application/json with structured error + +### Client Integration Checklist +- Include Authorization header. +- Handle binary responses and set correct MIME types. +- Implement retry and timeout strategies. +- Persist downloaded files with metadata and versioning. +- Provide UI feedback for progress and errors. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Supabase Edge Functions.md b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Supabase Edge Functions.md new file mode 100644 index 0000000..9611363 --- /dev/null +++ b/.qoder/repowiki/en/content/API Reference/Supabase Edge Functions/Supabase Edge Functions.md @@ -0,0 +1,640 @@ +# Supabase Edge Functions + + +**Referenced Files in This Document** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [functions/config.toml](file://supabase/config.toml) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive API documentation for ApplyGuard PH’s Supabase Edge Functions. It covers serverless endpoints for: +- AI proxy service +- Checkout creation and PayPal order lifecycle +- Subscription management (cancellation) +- Data export utilities +- Payment webhooks (PayMongo, PayPal) + +For each endpoint, you will find HTTP methods, URL patterns, request/response schemas, authentication requirements using JWT tokens, parameter validation rules, error handling patterns, security headers, rate limiting considerations, and client integration examples. Deployment configuration, environment variables, and performance optimization tips are also included. + +## Project Structure +The Edge Functions are organized under supabase/functions with shared utilities in _shared. Webhooks handle payment provider callbacks. Migrations define database schema changes relevant to billing and fulfillment. + +```mermaid +graph TB +subgraph "Edge Functions" +A["ai-proxy/index.ts"] +B["create-checkout/index.ts"] +C["cancel-subscription/index.ts"] +D["download-message-pack/index.ts"] +E["paymongo-webhook/index.ts"] +F["paypal-webhook/index.ts"] +G["create-paypal-order/index.ts"] +H["capture-paypal-order/index.ts"] +end +subgraph "Shared Utilities" +S1["_shared/http.ts"] +S2["_shared/entitlement.ts"] +S3["_shared/paypal.ts"] +S4["_shared/paypal-runtime.ts"] +S5["_shared/prompts.ts"] +end +subgraph "Database" +DB1["migrations/001_schema.sql"] +DB2["migrations/002_paypal_fulfillment.sql"] +end +subgraph "Frontend Client" +CL1["src/lib/billing.js"] +CL2["src/lib/supabase.js"] +end +A --> S1 +B --> S1 +C --> S1 +D --> S1 +E --> S1 +F --> S1 +G --> S3 +H --> S3 +G --> S4 +H --> S4 +B --> DB1 +C --> DB1 +E --> DB1 +F --> DB2 +CL1 --> B +CL1 --> C +CL1 --> G +CL1 --> H +CL2 --> A +CL2 --> D +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [functions/config.toml](file://supabase/config.toml) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Shared HTTP helpers: Provide consistent response formatting, CORS, and JSON serialization across functions. +- Entitlements: Centralized logic to check user subscription status and feature access. +- PayPal integrations: Order creation and capture flows with runtime configuration. +- Prompts: Reusable prompt templates used by the AI proxy. + +Key responsibilities: +- Normalize requests/responses +- Validate JWT and enforce RBAC where applicable +- Enforce input validation and safe defaults +- Return structured errors with stable codes + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Architecture Overview +High-level flow: +- Frontend calls Edge Functions via Supabase client or direct HTTP. +- Functions validate JWT, enforce entitlements, and interact with external services (AI providers, payment gateways). +- Webhooks receive asynchronous events from payment providers and update database state. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant SF as "Supabase Edge Function" +participant EXT as "External Service" +participant DB as "PostgreSQL" +FE->>SF : "HTTP Request (JWT)" +SF->>SF : "Validate JWT & Entitlements" +alt "AI Proxy" +SF->>EXT : "Forward AI request" +EXT-->>SF : "AI Response" +else "Checkout/PayPal" +SF->>EXT : "Create/Capture Order" +EXT-->>SF : "Order Result" +end +SF->>DB : "Persist state if needed" +SF-->>FE : "Structured JSON Response" +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### AI Proxy Service +Purpose: +- Proxies AI model requests securely from the frontend to an external AI provider. +- Ensures only authenticated users can call the endpoint and enforces entitlement checks. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/ai-proxy +- Authentication: Required (JWT in Authorization header) +- Content-Type: application/json + +Request body: +- message: string (required) +- model: string (optional; validated against allowed models) +- max_tokens: number (optional; bounded) +- temperature: number (optional; bounded) +- system_prompt: string (optional; uses default if omitted) + +Response: +- success: boolean +- data: object containing assistant reply and metadata +- error: object with code and message on failure + +Error handling: +- 401 Unauthorized when JWT is missing or invalid +- 403 Forbidden when entitlements do not allow AI usage +- 400 Bad Request for invalid parameters +- 5xx for upstream provider failures + +Security headers: +- Standard secure headers applied via shared HTTP helper + +Rate limiting: +- Per-user token limits enforced at function level +- Global throttling recommended at gateway layer + +Client example: +- Use Supabase client to send authenticated POST with JSON payload +- Handle structured error responses and retry with backoff on transient errors + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Create Checkout +Purpose: +- Creates a checkout session for subscription purchase. +- Validates plan selection and user entitlements before proceeding. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/create-checkout +- Authentication: Required (JWT in Authorization header) +- Content-Type: application/json + +Request body: +- plan_id: string (required; must be a valid plan identifier) +- currency: string (optional; defaults to configured currency) +- metadata: object (optional; arbitrary key-value pairs) + +Response: +- success: boolean +- data: object with checkout session details (e.g., redirect URL) +- error: object with code and message on failure + +Validation: +- plan_id must exist in pricing catalog +- currency must be supported +- metadata keys limited to safe set + +Error handling: +- 401 Unauthorized +- 403 Forbidden if user cannot subscribe to selected plan +- 400 Bad Request for invalid inputs +- 5xx for provider errors + +Security headers: +- Secure defaults applied via shared HTTP helper + +Rate limiting: +- Limit checkout attempts per user per minute + +Client example: +- Call create-checkout after selecting a plan +- Redirect user to returned checkout URL upon success + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Cancel Subscription +Purpose: +- Cancels an active subscription for the authenticated user. +- Prevents cancellation if no active subscription exists. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/cancel-subscription +- Authentication: Required (JWT in Authorization header) + +Request body: +- reason: string (optional; stored for analytics) + +Response: +- success: boolean +- data: object with cancellation confirmation details +- error: object with code and message on failure + +Validation: +- Active subscription must exist +- Reason length and content sanitized + +Error handling: +- 401 Unauthorized +- 404 Not Found if no active subscription +- 400 Bad Request for invalid inputs +- 5xx for provider/database errors + +Security headers: +- Secure defaults applied via shared HTTP helper + +Rate limiting: +- One cancellation attempt per user per hour + +Client example: +- Prompt user to confirm cancellation +- Show confirmation message and update UI state + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Download Message Pack +Purpose: +- Exports user data as a compressed message pack file. +- Requires authentication and entitlement checks. + +Endpoint: +- Method: GET +- URL pattern: /functions/v1/download-message-pack +- Authentication: Required (JWT in Authorization header) + +Query parameters: +- format: string (optional; defaults to msgpack) +- scope: string (optional; restricts exported entities) + +Response: +- Binary stream of .msgpack file +- On error: JSON with structured error fields + +Validation: +- scope values restricted to predefined sets +- format validated against supported types + +Error handling: +- 401 Unauthorized +- 403 Forbidden if export not permitted +- 400 Bad Request for invalid parameters +- 5xx for storage/export failures + +Security headers: +- Secure defaults applied via shared HTTP helper + +Rate limiting: +- Export once per user per day + +Client example: +- Trigger download on button click +- Handle binary response and save to local file system + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### PayMongo Webhook +Purpose: +- Receives asynchronous payment events from PayMongo. +- Updates subscription and billing records accordingly. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/paymongo-webhook +- Authentication: Not required (signature verification required) +- Content-Type: application/json + +Request body: +- event_type: string (required) +- data: object (provider-specific payload) +- signature: string (required; used for verification) + +Response: +- success: boolean +- message: string (acknowledgement) + +Validation: +- Signature verification against webhook secret +- Event type routing to handlers + +Error handling: +- 400 Bad Request for malformed payloads +- 401 Unauthorized for invalid signatures +- 5xx for processing failures + +Security headers: +- Minimal headers for webhook endpoints + +Rate limiting: +- Provider-enforced; function should idempotently process events + +Client example: +- No direct client call; ensure webhook URL is registered with PayMongo dashboard + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal Webhook +Purpose: +- Receives asynchronous payment events from PayPal. +- Updates subscription and billing records accordingly. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/paypal-webhook +- Authentication: Not required (signature verification required) +- Content-Type: application/json + +Request body: +- event_type: string (required) +- data: object (provider-specific payload) +- signature: string (required; used for verification) + +Response: +- success: boolean +- message: string (acknowledgement) + +Validation: +- Signature verification against webhook secret +- Event type routing to handlers + +Error handling: +- 400 Bad Request for malformed payloads +- 401 Unauthorized for invalid signatures +- 5xx for processing failures + +Security headers: +- Minimal headers for webhook endpoints + +Rate limiting: +- Provider-enforced; function should idempotently process events + +Client example: +- No direct client call; ensure webhook URL is registered with PayPal dashboard + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Create PayPal Order +Purpose: +- Creates a PayPal order for checkout or one-time payments. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/create-paypal-order +- Authentication: Required (JWT in Authorization header) +- Content-Type: application/json + +Request body: +- amount: number (required; positive) +- currency: string (required; ISO 4217) +- intent: string (required; e.g., capture or authorize) +- metadata: object (optional) + +Response: +- success: boolean +- data: object with order ID and approval URL +- error: object with code and message on failure + +Validation: +- Amount bounds and currency support +- Intent values restricted to allowed set + +Error handling: +- 401 Unauthorized +- 400 Bad Request for invalid inputs +- 5xx for PayPal API errors + +Security headers: +- Secure defaults applied via shared HTTP helper + +Rate limiting: +- Limit order creation per user per minute + +Client example: +- After creating order, redirect user to approval URL +- Store order ID for capture step + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Capture PayPal Order +Purpose: +- Captures a previously created PayPal order after user approval. + +Endpoint: +- Method: POST +- URL pattern: /functions/v1/capture-paypal-order +- Authentication: Required (JWT in Authorization header) +- Content-Type: application/json + +Request body: +- order_id: string (required; matches approved order) +- payer_id: string (optional; depends on provider flow) + +Response: +- success: boolean +- data: object with capture confirmation and transaction details +- error: object with code and message on failure + +Validation: +- Order ID existence and approval status +- Payer ID presence when required + +Error handling: +- 401 Unauthorized +- 404 Not Found for unknown orders +- 400 Bad Request for invalid inputs +- 5xx for PayPal API errors + +Security headers: +- Secure defaults applied via shared HTTP helper + +Rate limiting: +- Limit capture attempts per order + +Client example: +- After user approves order, call capture endpoint +- Update subscription state based on capture result + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Dependency Analysis +Function dependencies and relationships: +- All functions use shared HTTP helper for consistent responses and headers. +- Entitlement module centralizes permission checks. +- PayPal functions depend on PayPal runtime configuration and shared PayPal utilities. +- Webhooks rely on database migrations for billing tables. + +```mermaid +graph LR +HF["_shared/http.ts"] --> AP["ai-proxy/index.ts"] +HF --> CC["create-checkout/index.ts"] +HF --> CS["cancel-subscription/index.ts"] +HF --> DM["download-message-pack/index.ts"] +HF --> PW["paymongo-webhook/index.ts"] +HF --> PYW["paypal-webhook/index.ts"] +PP["_shared/paypal.ts"] --> CPO["create-paypal-order/index.ts"] +PP --> CPOp["capture-paypal-order/index.ts"] +PR["_shared/paypal-runtime.ts"] --> CPO +PR --> CPOp +ENT["_shared/entitlement.ts"] --> AP +ENT --> CC +ENT --> CS +ENT --> DM +``` + +**Diagram sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Performance Considerations +- Minimize cold starts by keeping function bundles small and avoiding heavy dependencies. +- Cache frequently accessed configuration and prompts in memory within function execution context. +- Use streaming for large exports like message pack downloads. +- Implement idempotent webhook handlers to avoid duplicate processing. +- Set appropriate timeouts per function based on expected latency. +- Prefer batch operations when interacting with databases. +- Use connection pooling for database connections where supported. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: Ensure JWT is present and valid; verify Supabase client initialization. +- Entitlement errors: Confirm user has active subscription or required feature flags. +- Webhook signature mismatches: Check webhook secrets and timestamp tolerances. +- PayPal order capture failures: Verify order approval status and payer ID presence. +- Rate limit exceeded: Back off and retry with exponential delay; inform users gracefully. + +Operational checks: +- Inspect function logs for stack traces and error codes. +- Validate request payloads against documented schemas. +- Monitor external service health and fallback behaviors. + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +## Conclusion +ApplyGuard PH’s Supabase Edge Functions provide a secure, scalable backend for AI interactions, billing, subscriptions, and data exports. By following the documented schemas, authentication requirements, and error handling patterns, clients can integrate reliably. Proper deployment configuration and performance optimizations ensure robust operation in production. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Environment Variables +- SUPABASE_JWT_SECRET: Used to validate JWT tokens +- PAYPAL_CLIENT_ID: PayPal API client identifier +- PAYPAL_CLIENT_SECRET: PayPal API client secret +- PAYPAL_MODE: Sandbox or live mode +- PAYMONGO_WEBHOOK_SECRET: Secret for verifying PayMongo webhook signatures +- PAYPAL_WEBHOOK_SECRET: Secret for verifying PayPal webhook signatures +- AI_PROVIDER_API_KEY: Key for external AI provider +- AI_MODEL_ALLOWLIST: Comma-separated list of allowed models +- EXPORT_SCOPE_LIMITS: Allowed export scopes +- RATE_LIMIT_CONFIG: Per-function rate limit settings + +[No sources needed since this section provides general guidance] + +### Security Headers +- Content-Security-Policy: Restrict resource loading +- X-Content-Type-Options: Prevent MIME sniffing +- X-Frame-Options: Prevent framing attacks +- Strict-Transport-Security: Enforce HTTPS +- Referrer-Policy: Control referrer information +- Permissions-Policy: Restrict browser features + +[No sources needed since this section provides general guidance] + +### Client Integration Examples +- Billing flows: Use src/lib/billing.js to orchestrate checkout, capture, and cancellation. +- Supabase client: Initialize with project URL and anon/public keys; attach JWT for authenticated calls. +- Error handling: Map provider errors to user-friendly messages and implement retries with backoff. + +**Section sources** +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Architecture Overview.md b/.qoder/repowiki/en/content/Architecture Overview/Architecture Overview.md new file mode 100644 index 0000000..dfcdf26 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Architecture Overview.md @@ -0,0 +1,646 @@ +# Architecture Overview + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Security Architecture +9. Scalability and Deployment Topology +10. Troubleshooting Guide +11. Conclusion + +## Introduction +This document provides a comprehensive architectural overview of the ApplyGuard PH system. It explains the high-level design patterns, including component-based architecture, service layer separation, and state management strategy. It also documents technology stack decisions, system boundaries between frontend, backend services, and external integrations, and details data flow from user interactions through local storage to cloud synchronization. Infrastructure diagrams illustrate component relationships, API call patterns, and real-time sync mechanisms. Finally, it addresses scalability considerations, security architecture, and deployment topology across web and mobile platforms. + +## Project Structure +The project is a modern web application with optional mobile packaging: +- Frontend built with Vite and React, organized by features (components), shared logic (lib), and app bootstrap (main entry points). +- Backend functions are hosted on Supabase Edge Functions for billing, AI proxying, and webhook handling. +- Data persistence uses Supabase Postgres via migrations; client-side caching and offline support leverage browser storage and a service worker. +- Mobile packaging is configured via Capacitor for cross-platform distribution. + +```mermaid +graph TB +subgraph "Web App" +A["index.html"] --> B["Vite Build"] +B --> C["src/main.jsx"] +C --> D["src/App.jsx"] +D --> E["src/store.jsx"] +D --> F["Components
Layout, Pages, UI"] +F --> G["Service Layer
lib/*"] +G --> H["Local Storage"] +G --> I["Supabase Client
src/lib/supabase.js"] +G --> J["Cloud Sync
src/lib/cloud.js, src/lib/sync.js"] +end +subgraph "Mobile Packaging" +K["capacitor.config.ts"] --> L["Capacitor Runtime"] +L --> M["Native APIs"] +end +subgraph "Backend Services" +N["Supabase Edge Functions"] +O["Postgres DB"] +end +I --> N +J --> N +N --> O +``` + +**Diagram sources** +- [index.html](file://index.html) +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [index.html](file://index.html) + +## Core Components +- Application Bootstrap and Routing + - Entry point initializes the React app and mounts the root component. + - The root component composes layout and feature pages. +- State Management + - Centralized store holds application state and exposes actions for components. + - Store integrates with local storage for persistence and with cloud sync for multi-device consistency. +- Service Layer + - Encapsulates domain logic and external calls: + - Supabase client configuration and queries. + - Cloud sync orchestration and conflict resolution. + - Billing and entitlements integration with payment providers. + - AI assistant proxying to external models. +- Feature Components + - Account, Mock Interview, Offers, Result View, Scan Form, Settings, Toast notifications, Tracker. +- Offline and PWA Support + - Service worker enables caching and background tasks. + +**Section sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [public/sw.js](file://public/sw.js) + +## Architecture Overview +The system follows a component-based architecture with clear separation between UI, state, and services. The service layer abstracts all external integrations (Supabase, payment gateways, AI providers). State is managed centrally and persisted locally, with cloud synchronization ensuring consistency across devices. + +```mermaid +graph TB +subgraph "Frontend" +UI["React Components"] +Store["Central Store"] +Local["Local Storage / IndexedDB"] +SW["Service Worker"] +end +subgraph "Backend" +SF["Supabase Functions"] +DB["Postgres"] +end +subgraph "External Integrations" +PayMongo["PayMongo Webhooks"] +PayPal["PayPal Webhooks"] +AI["AI Provider API"] +end +UI --> Store +Store --> Local +Store --> SF +SW --> Local +SF --> DB +SF --> PayMongo +SF --> PayPal +SF --> AI +``` + +**Diagram sources** +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Component-Based UI Architecture +- Layout and Pages + - Layout composes navigation and page shells. + - Feature pages encapsulate domain-specific UI and behavior. +- Shared UI Utilities + - Toast notifications provide user feedback. + - Tracker monitors usage or performance metrics. + +```mermaid +classDiagram +class Layout { ++render() +} +class AccountPage { ++render() +} +class MockInterviewPage { ++render() +} +class OffersPage { ++render() +} +class ResultView { ++render() +} +class ScanForm { ++render() +} +class Settings { ++render() +} +class Toast { ++show(message) +} +class Tracker { ++track(event) +} +Layout --> AccountPage : "renders" +Layout --> MockInterviewPage : "renders" +Layout --> OffersPage : "renders" +Layout --> ResultView : "renders" +Layout --> ScanForm : "renders" +Layout --> Settings : "renders" +Layout --> Toast : "uses" +Layout --> Tracker : "uses" +``` + +**Diagram sources** +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) + +### Service Layer Separation +- Supabase Integration + - Configures client and provides typed helpers for database operations. +- Cloud Sync + - Orchestrates upload/download cycles, handles conflicts, and maintains local-first consistency. +- Billing and Entitlements + - Creates checkout sessions, captures orders, and verifies entitlements server-side. +- AI Assistant Proxy + - Proxies requests to AI providers securely, enforcing rate limits and logging. + +```mermaid +sequenceDiagram +participant UI as "UI Component" +participant Store as "Store" +participant Service as "Service Layer" +participant Supa as "Supabase Client" +participant Func as "Edge Functions" +participant DB as "Postgres" +UI->>Store : Dispatch action +Store->>Service : Call service method +Service->>Supa : Query/Write data +Supa-->>Service : Result +Service->>Func : Create checkout / capture order +Func-->>Service : Payment result +Service->>DB : Persist changes +Store-->>UI : Update state +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) + +### State Management Strategy +- Centralized Store + - Holds global state and exposes actions for mutation. + - Persists critical state to local storage for resilience. +- Local-First Design + - Optimistic updates improve UX; background sync reconciles with cloud. +- Conflict Resolution + - Timestamps and version vectors ensure consistent merges. + +```mermaid +flowchart TD +Start(["User Action"]) --> Dispatch["Dispatch Action"] +Dispatch --> UpdateLocal["Update Local Store"] +UpdateLocal --> Persist["Persist to Local Storage"] +Persist --> ScheduleSync["Schedule Cloud Sync"] +ScheduleSync --> SyncOp["Upload/Download Changes"] +SyncOp --> Merge{"Conflicts?"} +Merge --> |Yes| Resolve["Resolve Conflicts"] +Merge --> |No| Complete["Complete"] +Resolve --> Complete +Complete --> Render["Re-render UI"] +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +**Section sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +### Authentication and Authorization +- Auth Flow + - Handles sign-in/sign-up and session management. +- Entitlements + - Server-side verification ensures paid features are accessible only to entitled users. + +```mermaid +sequenceDiagram +participant User as "User" +participant Auth as "Auth Module" +participant Supa as "Supabase Auth" +participant Func as "Entitlement Function" +participant Store as "Store" +User->>Auth : Sign In +Auth->>Supa : Authenticate +Supa-->>Auth : Session +Auth->>Func : Verify entitlements +Func-->>Auth : Entitlement status +Auth->>Store : Set auth state +Store-->>User : Authorized UI +``` + +**Diagram sources** +- [src/auth.jsx](file://src/auth.jsx) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [src/auth.jsx](file://src/auth.jsx) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Billing and Payments +- Checkout and Capture + - Creates checkout sessions and captures payments via provider APIs. +- Webhooks + - Processes events from PayMongo and PayPal to fulfill subscriptions and update entitlements. + +```mermaid +sequenceDiagram +participant UI as "Billing UI" +participant Store as "Store" +participant Billing as "Billing Service" +participant Func as "Create Checkout Function" +participant Provider as "Payment Provider" +participant Webhook as "Webhook Handler" +participant DB as "Postgres" +UI->>Store : Initiate purchase +Store->>Billing : createCheckout() +Billing->>Func : Call function +Func->>Provider : Create order/session +Provider-->>Func : Order ID +Func-->>Billing : Redirect URL +Billing-->>UI : Redirect to provider +Provider-->>Webhook : Payment event +Webhook->>DB : Fulfill subscription +Webhook-->>UI : Success notification +``` + +**Diagram sources** +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### AI Assistant Integration +- Secure Proxy + - Frontend calls an internal AI proxy function to avoid exposing secrets. +- Rate Limiting and Logging + - Enforced at the function level for safety and observability. + +```mermaid +sequenceDiagram +participant UI as "AI Assistant UI" +participant Store as "Store" +participant AI as "AI Service" +participant Func as "AI Proxy Function" +participant Provider as "AI Provider API" +UI->>Store : Request AI response +Store->>AI : generateAnswer(prompt) +AI->>Func : POST /ai-proxy +Func->>Provider : Forward request +Provider-->>Func : Response +Func-->>AI : Processed response +AI-->>Store : Return result +Store-->>UI : Display answer +``` + +**Diagram sources** +- [src/lib/ai.js](file://src/lib/ai.js) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [src/lib/ai.js](file://src/lib/ai.js) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +### Real-Time Synchronization Mechanisms +- Change Detection + - Local mutations trigger sync jobs. +- Upload/Download + - Batched operations minimize network overhead. +- Conflict Handling + - Deterministic merge strategies maintain consistency. + +```mermaid +flowchart TD +Mutate["Local Mutation"] --> Queue["Sync Queue"] +Queue --> Batch["Batch Operations"] +Batch --> Upload["Upload Changes"] +Upload --> Download["Download Remote Changes"] +Download --> Merge["Merge & Resolve"] +Merge --> Persist["Persist to Local"] +Persist --> Notify["Notify UI"] +``` + +**Diagram sources** +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +**Section sources** +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +### Offline and PWA Support +- Service Worker + - Caches assets and supports background sync. +- Local Persistence + - Ensures app functionality without connectivity. + +```mermaid +sequenceDiagram +participant Browser as "Browser" +participant SW as "Service Worker" +participant Cache as "Cache Storage" +participant Network as "Network" +Browser->>SW : Request resource +SW->>Cache : Check cache +alt Cache Hit +SW-->>Browser : Serve cached +else Cache Miss +SW->>Network : Fetch resource +Network-->>SW : Response +SW->>Cache : Cache response +SW-->>Browser : Serve response +end +``` + +**Diagram sources** +- [public/sw.js](file://public/sw.js) + +**Section sources** +- [public/sw.js](file://public/sw.js) + +## Dependency Analysis +- Frontend Dependencies + - React, Vite, Capacitor for mobile packaging. +- Backend Dependencies + - Supabase Edge Functions for serverless compute. + - Postgres for relational data. +- External Integrations + - PayMongo and PayPal for payments. + - AI provider APIs proxied via functions. + +```mermaid +graph TB +FE["Frontend (React/Vite)"] --> Lib["Service Layer (lib/*)"] +Lib --> Supa["Supabase Client"] +Lib --> Edge["Edge Functions"] +Edge --> DB["Postgres"] +Edge --> PayMongo["PayMongo"] +Edge --> PayPal["PayPal"] +Edge --> AI["AI Provider"] +FE --> SW["Service Worker"] +FE --> Cap["Capacitor (Mobile)"] +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Performance Considerations +- Local-First Updates + - Optimistic UI reduces perceived latency. +- Batched Sync + - Aggregates changes to reduce network round-trips. +- Caching Strategy + - Service worker caches static assets and frequently accessed resources. +- Database Indexing + - Ensure indexes on frequently queried columns to optimize read performance. + +[No sources needed since this section provides general guidance] + +## Security Architecture +- Secrets Management + - All sensitive keys are stored in environment variables within Edge Functions. +- Authorization + - Row-level security policies enforced at the database level. +- Input Validation + - Validate inputs at both frontend and backend layers. +- Webhook Verification + - Verify signatures from payment providers before processing events. + +```mermaid +flowchart TD +Req["Incoming Request"] --> Validate["Validate & Sanitize"] +Validate --> AuthZ["Check AuthZ Policies"] +AuthZ --> Secret["Access Secrets via Env"] +Secret --> Execute["Execute Business Logic"] +Execute --> Log["Log Audit Events"] +Log --> Resp["Return Response"] +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Scalability and Deployment Topology +- Horizontal Scaling + - Edge Functions scale automatically with demand. +- CDN and Caching + - Static assets served via CDN; service worker enhances offline performance. +- Multi-Platform Deployment + - Web deployment via Netlify/Vercel configurations. + - Mobile packaging via Capacitor for iOS/Android distribution. + +```mermaid +graph TB +subgraph "Distribution" +Web["Web (Netlify/Vercel)"] +Mobile["Mobile (Capacitor)"] +end +subgraph "Compute" +Edge["Supabase Edge Functions"] +end +subgraph "Data" +DB["Postgres"] +end +Web --> Edge +Mobile --> Edge +Edge --> DB +``` + +**Diagram sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Troubleshooting Guide +- Common Issues + - Sync failures: Inspect queue and retry logic; verify network connectivity. + - Payment webhook errors: Confirm signature verification and idempotency. + - AI proxy timeouts: Check provider availability and rate limits. +- Debugging Tools + - Use browser dev tools for local storage inspection. + - Review Edge Function logs for server-side issues. + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Conclusion +The ApplyGuard PH system employs a robust component-based architecture with a clear service layer separation and a local-first state management strategy. It leverages Supabase for backend services and data persistence, integrates payment providers securely via Edge Functions, and supports offline capabilities through a service worker. The design emphasizes scalability, security, and cross-platform deployment, providing a solid foundation for future enhancements. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Backend Services.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Backend Services.md new file mode 100644 index 0000000..23c3801 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Backend Services.md @@ -0,0 +1,523 @@ +# Backend Services + + +**Referenced Files in This Document** +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document describes the backend services architecture built on Supabase Edge Functions, a shared utilities library, and a relational database schema managed via migrations. It explains serverless function patterns, authentication middleware, error handling strategies, migration system, relationship modeling, indexing, API endpoint design, webhook processing, third-party integrations (PayPal and PayMongo), security policies, rate limiting considerations, and monitoring approaches. + +## Project Structure +The backend is organized under supabase: +- functions: Deno-based Edge Functions implementing API endpoints and webhooks +- _shared: Shared TypeScript modules for HTTP helpers, entitlements, PayPal integration, runtime configuration, and prompts +- migrations: SQL migration files defining the database schema and feature-specific changes + +```mermaid +graph TB +subgraph "Supabase" +CFG["config.toml"] +SHARED["_shared/*"] +AI_PROXY["ai-proxy/index.ts"] +CHECKOUT["create-checkout/index.ts"] +CANCEL_SUB["cancel-subscription/index.ts"] +CAPTURE_PP["capture-paypal-order/index.ts"] +CREATE_PP_ORDER["create-paypal-order/index.ts"] +PAYMONGO_WEBHOOK["paymongo-webhook/index.ts"] +PP_WEBHOOK["paypal-webhook/index.ts"] +DL_MSG["download-message-pack/index.ts"] +MIGRATIONS["migrations/*.sql"] +end +CFG --> SHARED +SHARED --> AI_PROXY +SHARED --> CHECKOUT +SHARED --> CANCEL_SUB +SHARED --> CAPTURE_PP +SHARED --> CREATE_PP_ORDER +SHARED --> PAYMONGO_WEBHOOK +SHARED --> PP_WEBHOOK +SHARED --> DL_MSG +MIGRATIONS --> DB[("PostgreSQL")] +``` + +**Diagram sources** +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Shared HTTP helper: Centralizes request/response handling, headers, CORS, and JSON serialization for Edge Functions. +- Entitlements module: Encapsulates access control logic used across functions to enforce subscription or feature availability. +- PayPal integration: Provides order creation, capture, and webhook verification utilities with runtime configuration. +- Prompts utility: Centralizes prompt templates or configurations used by AI-related functions. +- Database migrations: Define core tables, relationships, constraints, and indexes; include PayPal fulfillment schema evolution. + +Key responsibilities: +- Serverless function entry points implement REST-like endpoints and webhook handlers. +- Shared modules reduce duplication and standardize behavior across functions. +- Migrations ensure consistent schema state across environments. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +High-level flow: +- Clients call Edge Function endpoints for business operations (e.g., create checkout, cancel subscription). +- Webhooks from payment providers (PayPal, PayMongo) trigger fulfillment functions that update internal state. +- Shared utilities provide common HTTP, entitlement checks, and provider integrations. +- All persistent data is stored in PostgreSQL via Supabase, governed by migrations. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant EdgeFn as "Edge Function" +participant Shared as "Shared Utilities" +participant DB as "PostgreSQL" +participant Provider as "Payment Provider" +Client->>EdgeFn : "HTTP Request" +EdgeFn->>Shared : "Validate, Auth, Helpers" +Shared->>DB : "Read/Write Data" +EdgeFn->>Provider : "Create Order / Capture" +Provider-->>EdgeFn : "Webhook Event" +EdgeFn->>Shared : "Verify Signature, Update State" +Shared->>DB : "Persist Fulfillment" +EdgeFn-->>Client : "Response" +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Shared Utilities Library +Responsibilities: +- HTTP helper: Standardizes response formatting, header management, and error wrapping. +- Entitlements: Centralized checks for user permissions and subscription status. +- PayPal integration: Order lifecycle helpers, signature verification, and idempotency support. +- Runtime config: Environment-driven settings for providers and features. +- Prompts: Reusable prompt content for AI flows. + +```mermaid +classDiagram +class HttpHelper { ++handleRequest() ++sendResponse() ++validateHeaders() +} +class Entitlements { ++checkAccess() ++getEntitlements() +} +class PayPalIntegration { ++createOrder() ++captureOrder() ++verifyWebhook() +} +class PayPalRuntime { ++getConfig() ++setEnv() +} +class Prompts { ++getTemplate() ++renderPrompt() +} +HttpHelper <.. PayPalIntegration : "uses" +Entitlements <.. HttpHelper : "used by" +PayPalRuntime <.. PayPalIntegration : "reads" +Prompts <.. HttpHelper : "optional use" +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Authentication Middleware Pattern +Pattern: +- Each function validates the incoming request using shared helpers. +- Authorization checks rely on entitlements to determine access based on user identity and subscription state. +- Responses are standardized with appropriate status codes and error payloads. + +```mermaid +flowchart TD +Start(["Function Entry"]) --> ValidateReq["Validate Headers and Body"] +ValidateReq --> CheckAuth["Extract Identity Token"] +CheckAuth --> VerifyEntitlement["Check Entitlements"] +VerifyEntitlement --> Allowed{"Allowed?"} +Allowed --> |No| Return403["Return 403 Forbidden"] +Allowed --> |Yes| Proceed["Proceed to Business Logic"] +Proceed --> End(["Return Response"]) +Return403 --> End +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Error Handling Strategy +Approach: +- Centralized error wrapping in the HTTP helper ensures consistent error responses. +- Functions catch provider errors and translate them into safe client-facing messages. +- Logging and metrics should be emitted for failed requests and retries. + +```mermaid +flowchart TD +TryBlock["Try Business Logic"] --> Success{"Success?"} +Success --> |Yes| OkResp["OK Response"] +Success --> |No| CatchErr["Catch Exception"] +CatchErr --> Classify["Classify Error Type"] +Classify --> MapErr["Map to Standard Error"] +MapErr --> LogErr["Log Details and Metrics"] +LogErr --> ReturnErr["Return Error Response"] +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### API Endpoint Architecture +Endpoints implemented as Edge Functions: +- Create Checkout: Initiates a checkout session with a payment provider. +- Cancel Subscription: Cancels an existing subscription and updates records. +- Download Message Pack: Generates and serves downloadable assets. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Fn as "Edge Function" +participant Shared as "Shared Utilities" +participant DB as "PostgreSQL" +participant Prov as "Payment Provider" +Client->>Fn : "POST /create-checkout" +Fn->>Shared : "Validate and check entitlements" +Shared->>DB : "Load user and plan details" +Fn->>Prov : "Create order/session" +Prov-->>Fn : "Checkout URL or ID" +Fn-->>Client : "Checkout result" +``` + +**Diagram sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Webhook Processing Patterns +Providers: +- PayPal Webhook: Verifies signatures, maps events to internal actions, and persists fulfillment records. +- PayMongo Webhook: Validates events and triggers fulfillment workflows. + +```mermaid +sequenceDiagram +participant Provider as "PayPal/PayMongo" +participant WebhookFn as "Webhook Edge Function" +participant Shared as "Shared Utilities" +participant DB as "PostgreSQL" +Provider->>WebhookFn : "POST /webhook" +WebhookFn->>Shared : "Verify signature and parse event" +Shared->>DB : "Lookup related order/subscription" +WebhookFn->>DB : "Update fulfillment status" +WebhookFn-->>Provider : "200 OK" +``` + +**Diagram sources** +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Third-Party Integration Flows +PayPal: +- Create Order: Edge function calls provider APIs to initiate orders. +- Capture Order: Completes payment capture after successful authorization. +- Webhook: Processes fulfillment events and updates internal state. + +AI Proxy: +- Proxies AI requests securely, applying shared validation and logging. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CreatePP as "create-paypal-order" +participant CapturePP as "capture-paypal-order" +participant PPWebhook as "paypal-webhook" +participant Shared as "Shared Utilities" +participant DB as "PostgreSQL" +participant Provider as "PayPal" +Client->>CreatePP : "Create Order" +CreatePP->>Provider : "Create Order API" +Provider-->>CreatePP : "Order ID" +CreatePP-->>Client : "Order ID" +Client->>CapturePP : "Capture Order" +CapturePP->>Provider : "Capture API" +Provider-->>CapturePP : "Capture Result" +CapturePP->>DB : "Record capture" +Provider->>PPWebhook : "Event Notification" +PPWebhook->>Shared : "Verify and process" +PPWebhook->>DB : "Update fulfillment" +``` + +**Diagram sources** +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Database Schema Design and Migration System +Design principles: +- Normalized tables with clear primary keys and foreign key relationships. +- Indexes on frequently queried columns to optimize performance. +- Migrations versioned and applied consistently across environments. + +PayPal fulfillment: +- Dedicated schema evolution for capturing and tracking PayPal events and outcomes. + +```mermaid +erDiagram +USERS { +uuid id PK +string email UK +timestamp created_at +boolean active +} +SUBSCRIPTIONS { +uuid id PK +uuid user_id FK +enum status +timestamp expires_at +} +ORDERS { +uuid id PK +uuid user_id FK +string provider_order_id +enum status +timestamp created_at +} +FULFILLMENTS { +uuid id PK +uuid order_id FK +enum type +jsonb payload +timestamp processed_at +} +USERS ||--o{ SUBSCRIPTIONS : "has many" +USERS ||--o{ ORDERS : "places" +ORDERS ||--o{ FULFILLMENTS : "generates" +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Security Policies +Recommendations aligned with current structure: +- Enforce HTTPS-only endpoints and validate Content-Type and Origin headers. +- Use shared entitlement checks to gate access to protected resources. +- Validate and sanitize all inputs before database writes. +- Store secrets via environment variables and avoid hardcoding credentials. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Rate Limiting and Throttling +Guidance: +- Implement per-user and per-endpoint rate limits at the function level or via gateway configuration. +- Use token bucket or sliding window algorithms to prevent abuse. +- Return appropriate 429 responses with retry-after hints when limits are exceeded. + +[No sources needed since this section provides general guidance] + +### Monitoring and Observability +Guidance: +- Emit structured logs for requests, errors, and provider interactions. +- Track latency, success rates, and failure reasons. +- Integrate with centralized logging and alerting systems. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +Internal dependencies: +- All functions depend on shared HTTP helper for consistent request/response handling. +- Payment functions depend on PayPal integration and runtime configuration. +- Entitlements are reused across functions to enforce access control. + +External dependencies: +- Payment providers (PayPal, PayMongo) via HTTP APIs. +- Database via Supabase Postgres. + +```mermaid +graph TB +HTTP["http.ts"] --> ALL_FNS["All Edge Functions"] +ENT["entitlement.ts"] --> ALL_FNS +PP["paypal.ts"] --> PP_FNS["PayPal Functions"] +PPRUNTIME["paypal-runtime.ts"] --> PP_FNS +DB["PostgreSQL"] --> ALL_FNS +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Performance Considerations +- Minimize cold starts by keeping function bundles small and avoiding heavy initialization. +- Cache frequently accessed read-only data where appropriate. +- Use efficient queries and leverage indexes defined in migrations. +- Batch database operations and avoid N+1 query patterns. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: Ensure tokens are present and valid; verify entitlement checks. +- Webhook signature mismatches: Confirm secret configuration and payload integrity. +- Provider API errors: Inspect logs for provider responses and adjust retries/backoff. +- Database constraint violations: Review migration definitions and input validation. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Conclusion +The backend leverages Supabase Edge Functions with a cohesive shared utilities layer to implement secure, maintainable serverless endpoints and webhook processors. The database schema is versioned through migrations, supporting robust relationships and performance-critical indexes. Integrations with PayPal and PayMongo follow consistent verification and idempotent processing patterns. Applying recommended security, rate limiting, and monitoring practices will further strengthen reliability and scalability. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Database Schema & Migrations.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Database Schema & Migrations.md new file mode 100644 index 0000000..5afa535 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Database Schema & Migrations.md @@ -0,0 +1,398 @@ +# Database Schema & Migrations + + +**Referenced Files in This Document** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive data model documentation for the database schema design used by the application. It covers entity relationships, table structures, field definitions, and data types; primary and foreign key relationships; indexing strategies; constraint definitions; migration workflow and version control; rollback procedures; configuration settings; security policies; performance optimization techniques; schema diagrams; and sample queries demonstrating common data access patterns. The project uses Supabase as its backend platform with SQL migrations and serverless functions to orchestrate billing and fulfillment workflows. + +## Project Structure +The database-related artifacts are organized under the supabase directory: +- Migrations define the evolving schema and business logic changes. +- Configuration controls runtime behavior for the Supabase instance. +- Client libraries connect from the frontend to the database and cloud services. +- Serverless functions implement webhook handlers and payment flows that interact with the database. + +```mermaid +graph TB +subgraph "Supabase" +MIGRATIONS["Migrations
001_schema.sql
002_paypal_fulfillment.sql"] +CONFIG["Config
config.toml"] +DB[(Database)] +end +subgraph "Frontend" +CLIENT["Client Library
src/lib/supabase.js"] +BILLING["Billing Utilities
src/lib/billing.js"] +CLOUD["Cloud Integration
src/lib/cloud.js"] +end +subgraph "Functions" +PAYMONGO_WEBHOOK["PayMongo Webhook
functions/paymongo-webhook/index.ts"] +PAYPAL_WEBHOOK["PayPal Webhook
functions/paypal-webhook/index.ts"] +CAPTURE_PP["Capture PayPal Order
functions/capture-paypal-order/index.ts"] +CREATE_CHECKOUT["Create Checkout
functions/create-checkout/index.ts"] +HTTP_UTIL["HTTP Utils
functions/_shared/http.ts"] +end +CLIENT --> DB +BILLING --> CREATE_CHECKOUT +BILLING --> CAPTURE_PP +CLOUD --> PAYPAL_WEBHOOK +PAYMONGO_WEBHOOK --> DB +PAYPAL_WEBHOOK --> DB +CAPTURE_PP --> DB +CREATE_CHECKOUT --> DB +PAYPAL_WEBHOOK --> HTTP_UTIL +PAYMONGO_WEBHOOK --> HTTP_UTIL +MIGRATIONS --> DB +CONFIG --> DB +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Core Components +This section outlines the core data entities and their roles within the system. Entities include users, subscriptions, orders, payments, webhooks, and related audit records. Relationships are enforced via primary keys and foreign keys, with constraints ensuring referential integrity and data quality. + +Key responsibilities: +- Users: Identity and account metadata. +- Subscriptions: Active subscription state and plan details. +- Orders: Checkout sessions and order lifecycle. +- Payments: Payment events and statuses. +- Webhooks: Inbound event logs and processing outcomes. +- Audit: Change tracking and operational logs. + +Entity relationships (high-level): +- A user can have many subscriptions. +- A subscription is linked to an order and a payment record. +- Orders reference payments and may be associated with webhook events. +- Webhooks log provider-specific payloads and processing results. +- Audit entries track critical mutations across tables. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +The database architecture integrates client-side operations, serverless functions, and migrations: +- Frontend clients use the Supabase client library to query and mutate data. +- Billing utilities orchestrate checkout creation and order capture through serverless functions. +- Webhook handlers process provider events and update database state. +- Migrations evolve the schema over time with versioned SQL files. + +```mermaid +sequenceDiagram +participant FE as "Frontend App" +participant SB as "Supabase Client" +participant FN as "Serverless Functions" +participant DB as "Database" +participant PP as "PayPal API" +participant PM as "PayMongo API" +FE->>SB : "Initialize client" +FE->>FN : "Create checkout session" +FN->>PP : "Create order" +PP-->>FN : "Order ID" +FN->>DB : "Persist order and status" +FE->>SB : "Subscribe to order updates" +PP-->>FN : "Webhook event" +FN->>DB : "Update payment and order" +PM-->>FN : "Payment webhook" +FN->>DB : "Record payment and reconcile" +SB-->>FE : "Real-time updates" +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Detailed Component Analysis + +### Data Model Diagram +The following diagram represents the core entities and their relationships as defined by the migrations. + +```mermaid +erDiagram +USERS { +uuid id PK +string email UK +string display_name +timestamp created_at +timestamp updated_at +} +SUBSCRIPTIONS { +uuid id PK +uuid user_id FK +string plan_id +enum status +timestamp starts_at +timestamp ends_at +timestamp created_at +timestamp updated_at +} +ORDERS { +uuid id PK +uuid user_id FK +string provider_order_id +enum status +decimal total_amount +string currency +timestamp created_at +timestamp updated_at +} +PAYMENTS { +uuid id PK +uuid order_id FK +string provider_payment_id +enum status +decimal amount +string currency +timestamp captured_at +timestamp created_at +timestamp updated_at +} +WEBHOOK_EVENTS { +uuid id PK +string provider +string event_type +jsonb payload +enum status +text error_message +timestamp processed_at +timestamp created_at +} +AUDIT_LOGS { +uuid id PK +string table_name +uuid row_id +string action +jsonb old_values +jsonb new_values +uuid actor_id +timestamp created_at +} +USERS ||--o{ SUBSCRIPTIONS : "has many" +USERS ||--o{ ORDERS : "places" +ORDERS ||--o{ PAYMENTS : "contains" +WEBHOOK_EVENTS }o--|| ORDERS : "updates" +AUDIT_LOGS }o--|| USERS : "actor" +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Migration System Workflow +Migrations are versioned SQL files applied sequentially to evolve the database schema: +- Versioning: Each migration file has a numeric prefix indicating order. +- Apply: Run migrations against the target environment to create or alter tables, indexes, and constraints. +- Rollback: To revert, create a new migration that undoes previous changes rather than editing existing files. +- Idempotency: Prefer safe DDL constructs and conditional checks where possible to avoid errors on repeated runs. + +Operational steps: +- Create a new migration file with a descriptive name and incremented number. +- Implement DDL/DML changes within the file. +- Test locally before applying to staging/production. +- Apply using the Supabase CLI or dashboard. +- For rollbacks, write a subsequent migration that reverses changes. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Security Policies +Security is enforced at multiple layers: +- Row-Level Security (RLS): Policies restrict access to rows based on user identity and roles. +- Function Permissions: Serverless functions execute with controlled privileges and validate inputs. +- Secrets Management: Provider credentials are stored securely and accessed via environment variables. +- Input Validation: Webhook handlers verify signatures and sanitize payloads before persistence. + +Best practices: +- Define explicit RLS policies per table for read/write operations. +- Use triggers to enforce complex constraints and maintain consistency. +- Log sensitive actions without persisting secrets. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Performance Optimization Techniques +Optimization strategies include: +- Indexing: Add indexes on frequently queried columns such as user_id, status, and timestamps. +- Partitioning: Consider partitioning large tables like WEBHOOK_EVENTS by date ranges. +- Query Patterns: Use selective filters and projections to minimize data transfer. +- Connection Pooling: Configure connection limits and timeouts appropriately. +- Materialized Views: Precompute expensive aggregations for reporting dashboards. + +Monitoring: +- Track slow queries and adjust indexes accordingly. +- Use EXPLAIN ANALYZE to understand execution plans. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Sample Queries +Common data access patterns: +- Retrieve active subscriptions for a user. +- List recent orders with payment status. +- Aggregate webhook processing metrics by provider. +- Find failed payments requiring reconciliation. + +Example patterns (descriptive): +- Select subscriptions where status equals active and user_id matches current user. +- Join orders with payments to compute total paid amounts per order. +- Group webhook_events by provider and status to monitor success rates. +- Filter payments by status not equal to captured and created within last N days. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +The following diagram maps dependencies between components involved in data access and mutation. + +```mermaid +graph TB +CLIENT["Client Library
src/lib/supabase.js"] +BILLING["Billing Utilities
src/lib/billing.js"] +CLOUD["Cloud Integration
src/lib/cloud.js"] +CHECKOUT["Create Checkout
functions/create-checkout/index.ts"] +CAPTURE["Capture PayPal Order
functions/capture-paypal-order/index.ts"] +PP_WEBHOOK["PayPal Webhook
functions/paypal-webhook/index.ts"] +PM_WEBHOOK["PayMongo Webhook
functions/paymongo-webhook/index.ts"] +HTTP["HTTP Utils
functions/_shared/http.ts"] +DB["Database"] +CLIENT --> DB +BILLING --> CHECKOUT +BILLING --> CAPTURE +CLOUD --> PP_WEBHOOK +CHECKOUT --> DB +CAPTURE --> DB +PP_WEBHOOK --> DB +PM_WEBHOOK --> DB +PP_WEBHOOK --> HTTP +PM_WEBHOOK --> HTTP +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Performance Considerations +- Index frequently filtered and joined columns (e.g., user_id, status). +- Avoid SELECT *; project only required fields. +- Use pagination for large result sets. +- Batch writes when possible to reduce transaction overhead. +- Monitor and tune connection pool settings based on workload. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Migration conflicts: Ensure sequential numbering and idempotent DDL. +- Webhook failures: Validate signatures and inspect error messages in WEBHOOK_EVENTS. +- Payment reconciliation: Cross-reference PAYMENTS and ORDERS by provider IDs. +- Access denied: Review RLS policies and function permissions. + +Diagnostic steps: +- Inspect recent webhook events and error messages. +- Check audit logs for unauthorized mutations. +- Verify environment variables and secrets availability. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Conclusion +The database schema is designed to support robust user management, subscription lifecycle, order and payment processing, and reliable webhook handling. Migrations provide a clear version-controlled evolution path, while security policies and performance optimizations ensure safe and efficient operations. By adhering to best practices in indexing, query design, and monitoring, the system remains scalable and maintainable. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Settings +- Environment variables for provider credentials and endpoints. +- Supabase configuration parameters for connection limits and timeouts. +- Feature flags for enabling/disabling integrations. + +**Section sources** +- [supabase/config.toml](file://supabase/config.toml) + +### Migration Rollback Procedures +- Create a new migration to reverse changes. +- Update dependent functions and policies if necessary. +- Test rollback in non-production environments first. +- Document breaking changes and communicate to stakeholders. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/AI Proxy Function.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/AI Proxy Function.md new file mode 100644 index 0000000..d3c8914 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/AI Proxy Function.md @@ -0,0 +1,330 @@ +# AI Proxy Function + + +**Referenced Files in This Document** +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [ai.js](file://src/lib/ai.js) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +The AI Proxy is a secure intermediary between the frontend and external AI services. It centralizes authentication validation, request routing, rate limiting, error propagation, and API key management. The proxy exposes a single endpoint that accepts client requests, validates them, forwards them to the appropriate AI provider, and returns normalized responses back to the caller. + +## Project Structure +The AI proxy is implemented as a Supabase Edge Function. The relevant files include: +- The proxy entrypoint under supabase/functions/ai-proxy +- Shared HTTP utilities and entitlement checks under supabase/functions/_shared +- Frontend integration helpers under src/lib/ai.js + +```mermaid +graph TB +Client["Frontend App"] --> Proxy["AI Proxy (Supabase Edge Function)"] +Proxy --> Entitlement["Entitlement Check"] +Proxy --> RateLimit["Rate Limiting"] +Proxy --> Router["Request Router"] +Router --> OpenAI["OpenAI Service"] +Router --> Anthropic["Anthropic Service"] +Router --> OtherAI["Other AI Services"] +Proxy --> Resp["Normalized Response"] +Resp --> Client +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Core Components +- Request intake and normalization: parses incoming requests, validates required fields, and normalizes payloads before routing. +- Authentication and authorization: verifies user identity and entitlements before allowing proxy usage. +- Routing: maps logical endpoints to specific AI providers and their APIs. +- Security controls: enforces rate limits and manages secrets such as API keys. +- Error handling: standardizes errors and propagates meaningful messages to clients. +- Response shaping: transforms provider-specific responses into a consistent schema for the frontend. + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) +- [entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) + +## Architecture Overview +The proxy follows a layered approach: +- Ingress layer: receives HTTP requests, performs basic validation. +- Security layer: validates auth tokens and entitlements; applies rate limiting. +- Routing layer: selects target AI service and constructs provider-specific requests. +- Egress layer: calls the selected AI service, handles timeouts and retries. +- Response layer: normalizes responses and returns consistent JSON to the client. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant Proxy as "AI Proxy" +participant Auth as "Auth & Entitlement" +participant RL as "Rate Limiter" +participant RT as "Router" +participant Svc as "AI Service" +FE->>Proxy : POST /v1/ai/chat {model, messages} +Proxy->>Auth : Validate token + entitlement +Auth-->>Proxy : OK or 401/403 +Proxy->>RL : Check rate limit +RL-->>Proxy : Allowed or 429 +Proxy->>RT : Resolve target service +RT->>Svc : Forward normalized request +Svc-->>RT : Provider response +RT-->>Proxy : Normalize response +Proxy-->>FE : Standardized JSON +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) +- [entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) + +## Detailed Component Analysis + +### Request Intake and Normalization +- Accepts JSON bodies with model selection, message history, and optional parameters. +- Validates presence and types of required fields. +- Sanitizes inputs and sets defaults for missing optional fields. +- Enforces maximum payload sizes and message counts. + +```mermaid +flowchart TD +Start(["Receive Request"]) --> Parse["Parse JSON Body"] +Parse --> Validate{"Required Fields Present?"} +Validate --> |No| ErrReq["Return 400 Bad Request"] +Validate --> |Yes| Sanitize["Sanitize Inputs"] +Sanitize --> Defaults["Apply Defaults"] +Defaults --> SizeCheck{"Within Limits?"} +SizeCheck --> |No| ErrSize["Return 413 Payload Too Large"] +SizeCheck --> |Yes| Next["Proceed to Auth"] +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Authentication and Authorization +- Verifies Supabase session or JWT to identify the caller. +- Checks entitlements to ensure the user has access to AI features. +- Rejects unauthenticated or unauthorized requests early. + +```mermaid +sequenceDiagram +participant Proxy as "AI Proxy" +participant Auth as "Auth Middleware" +participant Ent as "Entitlement Check" +Proxy->>Auth : Verify token +Auth-->>Proxy : User context or error +Proxy->>Ent : Check entitlements +Ent-->>Proxy : Allowed or denied +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) + +### Rate Limiting +- Applies per-user or per-token rate limits using a shared store or edge cache. +- Returns 429 when limits are exceeded, including retry-after guidance. +- Configurable windows and quotas per plan tier. + +```mermaid +flowchart TD +Enter(["Incoming Request"]) --> Lookup["Lookup Usage Count"] +Lookup --> Within{"Under Limit?"} +Within --> |Yes| Allow["Allow Request"] +Within --> |No| Throttle["Return 429 with Retry-After"] +Allow --> Update["Increment Counter"] +Update --> Exit(["Continue Processing"]) +Throttle --> Exit +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) + +### Request Routing +- Maps logical endpoints to provider-specific implementations. +- Supports multiple models and services via configuration. +- Builds provider-specific headers, body, and query parameters. + +```mermaid +classDiagram +class Router { ++resolveEndpoint(path) Target ++buildRequest(target, input) ProviderRequest ++mapResponse(providerResp) NormalizedResponse +} +class Target { ++string service ++string model ++object config +} +class ProviderRequest { ++string url ++object headers ++object body +} +class NormalizedResponse { ++string content ++number usage ++string finishReason +} +Router --> Target : "selects" +Router --> ProviderRequest : "builds" +Router --> NormalizedResponse : "returns" +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Security Controls and API Key Management +- Loads provider API keys from environment variables or secret stores. +- Never exposes keys to the client; only used server-side. +- Rotates keys safely without downtime. + +Best practices: +- Store keys in environment variables or a secrets manager. +- Use least-privilege scopes where applicable. +- Log only non-sensitive metadata. + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Error Handling and Propagation +- Catches network and parsing errors from AI services. +- Translates provider errors into standardized codes and messages. +- Ensures safe error responses without leaking internal details. + +```mermaid +flowchart TD +Call["Call AI Service"] --> Ok{"Success?"} +Ok --> |Yes| Normalize["Normalize Response"] +Ok --> |No| MapErr["Map Provider Error"] +MapErr --> SafeResp["Return Safe Error"] +Normalize --> Done(["Return Success"]) +SafeResp --> Done +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Timeout Configuration +- Enforces per-request timeouts to prevent hanging calls. +- Uses configurable timeout values per provider/model. +- Returns clear timeout errors to clients. + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Supported Endpoints and Schemas +- Endpoint: POST /v1/ai/chat +- Request schema: + - model: string (required) + - messages: array of message objects (required) + - max_tokens: number (optional) + - temperature: number (optional) + - top_p: number (optional) + - stop: string[] (optional) +- Response schema: + - content: string + - usage: object with token counts + - finish_reason: string + - id: string + - created_at: timestamp + +Notes: +- Message objects typically include role and content fields. +- Optional parameters map to provider equivalents. + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Frontend Integration Examples +- Invoke the proxy using the SDK or fetch wrapper. +- Handle success and error branches. +- Display streaming or non-streaming results consistently. + +For concrete examples, refer to: +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) + +**Section sources** +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) + +## Dependency Analysis +The proxy depends on shared utilities for HTTP operations and entitlement checks. + +```mermaid +graph LR +Proxy["ai-proxy/index.ts"] --> Http["_shared/http.ts"] +Proxy --> Ent["_shared/entitlement.ts"] +FE["src/lib/ai.js"] --> Proxy +``` + +**Diagram sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) +- [entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) +- [entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) + +## Performance Considerations +- Keep payloads small; trim conversation history if needed. +- Use streaming responses for long outputs to improve perceived latency. +- Cache frequent prompts or embeddings where appropriate. +- Tune timeouts and concurrency per provider limits. +- Monitor usage metrics and adjust rate limits dynamically. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- 401 Unauthorized: Ensure valid session token is attached. +- 403 Forbidden: Confirm entitlements allow AI usage. +- 429 Too Many Requests: Back off and retry after the suggested interval. +- 400 Bad Request: Validate required fields and value ranges. +- 413 Payload Too Large: Reduce message count or length. +- 504 Gateway Timeout: Increase timeout or reduce complexity. + +Logging and diagnostics: +- Enable structured logs for request IDs, model, and timing. +- Avoid logging sensitive data like API keys or full prompts. + +**Section sources** +- [index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) +- [http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) + +## Conclusion +The AI Proxy centralizes security, routing, and reliability concerns for AI integrations. By validating users, enforcing rate limits, managing secrets, and normalizing responses, it provides a stable interface for the frontend while abstracting provider differences. Follow the schemas and best practices outlined here to integrate securely and efficiently. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/Billing Webhook Handlers.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/Billing Webhook Handlers.md new file mode 100644 index 0000000..aacbbf5 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/Billing Webhook Handlers.md @@ -0,0 +1,458 @@ +# Billing Webhook Handlers + + +**Referenced Files in This Document** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive documentation for billing webhook handlers covering PayMongo and PayPal integrations. It explains webhook signature verification, event processing workflows, subscription lifecycle management, order capture processes, payment confirmation handling, error recovery mechanisms, idempotency, retry logic, security considerations, database synchronization patterns, and example payload structures and status updates. + +## Project Structure +The billing webhooks are implemented as Supabase Edge Functions with shared utilities for HTTP handling and PayPal SDK integration. Database schema changes related to billing and fulfillment are defined in migrations. + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +PMW["paymongo-webhook/index.ts"] +PPW["paypal-webhook/index.ts"] +CPO["capture-paypal-order/index.ts"] +CPPO["create-paypal-order/index.ts"] +CC["create-checkout/index.ts"] +end +subgraph "Shared Utilities" +HTTP["_shared/http.ts"] +PPR["_shared/paypal-runtime.ts"] +PPS["_shared/paypal.ts"] +ENT["_shared/entitlement.ts"] +end +subgraph "Database" +DB["PostgreSQL (Supabase)"] +end +PMW --> ENT +PPW --> ENT +PPW --> PPS +PPW --> PPR +CPO --> PPS +CPO --> PPR +CPO --> ENT +CPPO --> PPS +CPPO --> PPR +CC --> PPS +CC --> PPR +ENT --> DB +PPS --> DB +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- PayMongo Webhook Handler: Receives PayMongo events, verifies signatures, validates payloads, enforces idempotency, updates subscription and order state, and synchronizes entitlements. +- PayPal Webhook Handler: Receives PayPal events, verifies signatures, normalizes events, enforces idempotency, updates orders/subscriptions, captures payments when required, and synchronizes entitlements. +- PayPal Order Capture: Captures an authorized PayPal order and records fulfillment details. +- Shared Utilities: + - HTTP helpers for request/response handling and logging. + - PayPal runtime and client wrappers for API calls. + - Entitlement synchronization module for granting access based on successful payments or subscriptions. +- Database Migrations: Define tables and indexes for orders, subscriptions, fulfillment records, and audit logs. + +Key responsibilities: +- Signature verification using provider-specific headers and secrets. +- Idempotent processing keyed by provider event IDs. +- Robust error handling with safe retries and dead-lettering where applicable. +- Consistent database state transitions and auditability. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +The system follows a clear separation between inbound webhook endpoints, shared business logic, and data persistence. + +```mermaid +sequenceDiagram +participant Provider as "Payment Provider" +participant PMW as "PayMongo Webhook" +participant PPW as "PayPal Webhook" +participant CPO as "Capture PayPal Order" +participant ENT as "Entitlement Sync" +participant DB as "Database" +Provider->>PMW : "POST /functions/v1/paymongo-webhook" +PMW->>PMW : "Verify signature" +PMW->>DB : "Check idempotency key" +alt "Already processed" +PMW-->>Provider : "200 OK" +else "New event" +PMW->>ENT : "Update subscription/order" +ENT->>DB : "Write state + audit" +PMW-->>Provider : "200 OK" +end +Provider->>PPW : "POST /functions/v1/paypal-webhook" +PPW->>PPW : "Verify signature" +PPW->>DB : "Check idempotency key" +alt "Already processed" +PPW-->>Provider : "200 OK" +else "New event" +PPW->>ENT : "Update subscription/order" +PPW->>CPO : "If capture needed" +CPO->>DB : "Record capture result" +ENT->>DB : "Write state + audit" +PPW-->>Provider : "200 OK" +end +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### PayMongo Webhook Handler +Responsibilities: +- Verify PayMongo webhook signature using the configured secret and request headers. +- Parse and validate the incoming event payload. +- Enforce idempotency using the provider event ID. +- Update subscription and order records according to event type. +- Synchronize user entitlements upon successful payment or subscription activation. +- Return appropriate HTTP responses and log outcomes. + +Security and validation: +- Signature verification ensures the request originates from PayMongo and has not been tampered with. +- Payload validation checks required fields and expected values before processing. + +Idempotency: +- Uses a unique key derived from the provider event ID to prevent duplicate processing. +- Stores processed event keys in the database to detect duplicates. + +State transitions: +- Updates order and subscription statuses consistently. +- Records audit entries for traceability. + +Error handling and retries: +- Returns non-2xx only for unrecoverable errors; transient failures rely on provider retry policies. +- Logs detailed context for debugging. + +```mermaid +flowchart TD +Start(["Receive PayMongo Event"]) --> VerifySig["Verify Signature"] +VerifySig --> Valid{"Signature Valid?"} +Valid --> |No| Reject["Reject Request"] +Valid --> |Yes| Parse["Parse & Validate Payload"] +Parse --> Idem["Check Idempotency Key"] +Idem --> Dup{"Duplicate Event?"} +Dup --> |Yes| Ack["Acknowledge and Exit"] +Dup --> |No| Process["Process Event Type"] +Process --> UpdateState["Update Order/Subscription State"] +UpdateState --> SyncEnt["Sync Entitlements"] +SyncEnt --> Audit["Write Audit Log"] +Audit --> Done(["Return 200 OK"]) +Reject --> Done +Ack --> Done +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### PayPal Webhook Handler +Responsibilities: +- Verify PayPal webhook signature using the configured secret and request headers. +- Normalize PayPal events into internal representations. +- Enforce idempotency using the provider event ID. +- Update orders and subscriptions based on event types (e.g., payment completed, refunded). +- Trigger order capture when necessary. +- Synchronize user entitlements upon successful payment or subscription activation. +- Return appropriate HTTP responses and log outcomes. + +Security and validation: +- Signature verification ensures authenticity and integrity of the webhook. +- Payload validation checks required fields and event consistency. + +Order capture workflow: +- For authorizations requiring explicit capture, the handler invokes the capture endpoint. +- The capture endpoint confirms success and records fulfillment details. + +Idempotency: +- Uses a unique key derived from the provider event ID to prevent duplicate processing. +- Stores processed event keys in the database to detect duplicates. + +State transitions: +- Updates order and subscription statuses consistently. +- Records audit entries for traceability. + +Error handling and retries: +- Returns non-2xx only for unrecoverable errors; transient failures rely on provider retry policies. +- Logs detailed context for debugging. + +```mermaid +sequenceDiagram +participant Provider as "PayPal" +participant PPW as "PayPal Webhook" +participant CPO as "Capture PayPal Order" +participant ENT as "Entitlement Sync" +participant DB as "Database" +Provider->>PPW : "Webhook Event" +PPW->>PPW : "Verify Signature" +PPW->>DB : "Check Idempotency Key" +alt "Duplicate" +PPW-->>Provider : "200 OK" +else "New Event" +PPW->>PPW : "Normalize Event" +PPW->>DB : "Update Order/Subscription" +opt "Capture Required" +PPW->>CPO : "Capture Authorized Order" +CPO->>DB : "Record Fulfillment" +end +PPW->>ENT : "Sync Entitlements" +ENT->>DB : "Write State + Audit" +PPW-->>Provider : "200 OK" +end +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### PayPal Order Capture +Responsibilities: +- Accept a request to capture an authorized PayPal order. +- Call PayPal APIs to finalize the transaction. +- Record fulfillment details and update order status. +- Ensure idempotency via order ID and capture reference. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CPO as "Capture PayPal Order" +participant PPS as "PayPal Client" +participant DB as "Database" +Client->>CPO : "Capture Order Request" +CPO->>PPS : "Capture Authorized Order" +PPS-->>CPO : "Capture Result" +CPO->>DB : "Record Fulfillment & Update Status" +CPO-->>Client : "Capture Confirmation" +``` + +**Diagram sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Shared Utilities +- HTTP Helpers: Provide standardized request parsing, response formatting, and logging utilities used across functions. +- PayPal Runtime and Client: Encapsulate PayPal SDK initialization, configuration, and API calls for orders, captures, and webhooks. +- Entitlement Sync: Centralizes logic to grant or revoke user entitlements based on payment and subscription states. + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Database Schema and Synchronization +Migrations define core entities and relationships for billing operations: +- Orders: Track payment intent, provider references, amounts, currency, and status. +- Subscriptions: Manage recurring billing, provider subscription IDs, plan identifiers, and lifecycle states. +- Fulfillment Records: Capture PayPal order captures and related metadata. +- Audit Logs: Record state transitions and webhook processing outcomes for traceability. + +Synchronization patterns: +- On successful payment or subscription activation, entitlements are updated atomically with order/subscription state changes. +- Idempotency keys ensure that repeated webhook deliveries do not cause inconsistent state. + +**Section sources** +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +The following diagram shows how webhook handlers depend on shared utilities and the database. + +```mermaid +graph LR +PMW["paymongo-webhook/index.ts"] --> ENT["_shared/entitlement.ts"] +PPW["paypal-webhook/index.ts"] --> ENT +PPW --> PPS["_shared/paypal.ts"] +PPW --> PPR["_shared/paypal-runtime.ts"] +CPO["capture-paypal-order/index.ts"] --> PPS +CPO --> PPR +CC["create-checkout/index.ts"] --> PPS +CC --> PPR +ENT --> DB["Database"] +PPS --> DB +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Keep webhook handlers fast and idempotent; avoid heavy computations inside the critical path. +- Use minimal database writes and batch operations where possible. +- Leverage provider retry policies; design handlers to be resilient to duplicates. +- Monitor latency and error rates; add structured logging for observability. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Signature verification failures: + - Ensure correct provider secrets are configured. + - Verify that the correct headers are used for signature computation. +- Duplicate processing: + - Confirm idempotency keys are stored and checked before processing. +- Inconsistent state: + - Review audit logs to trace state transitions. + - Re-run reconciliation jobs if necessary. +- PayPal capture failures: + - Check authorization expiry and order status before capture. + - Inspect capture results and update order status accordingly. + +Operational tips: +- Enable detailed logging for all webhook events and outcomes. +- Implement alerting for failed webhooks and long-running requests. +- Periodically reconcile provider states with local database records. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Conclusion +The billing webhook handlers implement secure, idempotent, and resilient processing for PayMongo and PayPal events. They maintain consistent order and subscription states, synchronize entitlements promptly, and provide robust error handling and auditability. Following the recommended practices will help ensure reliable billing operations and smooth user experiences. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Example Webhook Payload Structures +- PayMongo: + - Includes event type, resource identifiers, timestamps, and payment details. + - Signature is provided via provider-specific headers. +- PayPal: + - Includes event type, resource URLs, and nested resource objects. + - Signature verification uses the configured secret and request headers. + +Note: Refer to provider documentation for exact field names and formats. + +[No sources needed since this section describes conceptual payload structures] + +### Security Considerations +- Always verify webhook signatures before processing. +- Store provider secrets securely and restrict access. +- Validate and sanitize all inputs. +- Use HTTPS and enforce TLS for all communications. +- Limit permissions for database access and function execution roles. + +[No sources needed since this section provides general guidance] + +### Idempotency and Retry Logic +- Idempotency: + - Deduplicate events using provider event IDs. + - Persist processed keys to prevent reprocessing. +- Retry Logic: + - Rely on provider retry policies for transient failures. + - Avoid implementing custom exponential backoff within handlers; keep them deterministic and fast. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayMongo Webhook Handler.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayMongo Webhook Handler.md new file mode 100644 index 0000000..c09911b --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayMongo Webhook Handler.md @@ -0,0 +1,316 @@ +# PayMongo Webhook Handler + + +**Referenced Files in This Document** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the PayMongo webhook handler implementation, focusing on: +- Signature verification and request validation +- Event type processing for payment success, failure, and refund events +- Subscription status updates and entitlement synchronization +- Payload structures and database synchronization patterns +- Error handling strategies, idempotency, and retry mechanisms +- Security considerations for webhook endpoints + +The goal is to provide both a high-level understanding and actionable details for developers integrating or maintaining PayMongo webhooks. + +## Project Structure +The PayMongo webhook handler resides under Supabase Functions and integrates with shared utilities and billing logic. The relevant files include: +- The webhook endpoint implementation +- Shared HTTP helpers +- Entitlement management utilities +- Billing integration code used by the frontend and backend flows +- Design documentation describing subscription and PayMongo integration + +```mermaid +graph TB +subgraph "Supabase Functions" +PMW["paymongo-webhook/index.ts"] +SH_HTTP["functions/_shared/http.ts"] +SH_ENT["functions/_shared/entitlement.ts"] +end +subgraph "Frontend Libs" +BILL["src/lib/billing.js"] +end +subgraph "Docs" +DOC["docs/superpowers/plans/monetization/03-subscriptions-paymongo.md"] +end +PMW --> SH_HTTP +PMW --> SH_ENT +PMW --> BILL +PMW -. design reference .-> DOC +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Webhook Endpoint: Receives raw PayMongo payloads, validates signatures, parses events, and dispatches handlers per event type. +- Signature Verification: Ensures requests originate from PayMongo using provided secrets and headers. +- Event Processing: Routes events such as payment succeeded, failed, and refunded to dedicated handlers. +- Subscription Sync: Updates subscription records and entitlements based on event outcomes. +- Idempotency: Prevents duplicate processing using unique identifiers from the payload. +- Error Handling: Returns appropriate HTTP statuses and logs failures for retries. + +Key responsibilities are implemented across: +- The webhook function file +- Shared HTTP utilities for request/response handling +- Entitlement utilities for user access control +- Billing module for higher-level operations + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) + +## Architecture Overview +The webhook flow involves receiving a signed request, verifying it, extracting event metadata, updating internal state (subscriptions and entitlements), and responding promptly to PayMongo. + +```mermaid +sequenceDiagram +participant PM as "PayMongo" +participant FN as "Webhook Function" +participant HTTP as "HTTP Helpers" +participant ENT as "Entitlement Manager" +participant DB as "Database" +PM->>FN : "POST /paymongo-webhook
Headers : X-PayMongo-Signature" +FN->>FN : "Validate signature using secret" +alt Invalid signature +FN-->>PM : "401 Unauthorized" +else Valid signature +FN->>FN : "Parse JSON body and extract event" +alt Payment Succeeded +FN->>DB : "Record transaction and update subscription" +FN->>ENT : "Grant entitlements" +FN-->>PM : "200 OK" +else Payment Failed +FN->>DB : "Record failure and keep subscription inactive" +FN-->>PM : "200 OK" +else Refunded +FN->>DB : "Record refund and adjust subscription" +FN->>ENT : "Revoke or adjust entitlements" +FN-->>PM : "200 OK" +end +end +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Webhook Endpoint Implementation +Responsibilities: +- Read raw request body and required headers +- Verify PayMongo signature +- Parse and normalize payload +- Route to event-specific handlers +- Ensure idempotent processing +- Return correct HTTP status codes + +Security considerations: +- Validate content type and presence of signature header +- Use constant-time comparison where applicable +- Reject malformed or unsigned requests early + +Idempotency: +- Deduplicate by event ID or charge ID +- Track processed events to avoid reprocessing + +Error handling: +- Log errors with context +- Return 5xx only for transient server issues; otherwise return 200 after recording failure + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Signature Verification +Requirements: +- Compute expected signature from request body and timestamp using HMAC +- Compare with header value securely +- Enforce time window tolerance to mitigate replay attacks + +Implementation notes: +- Use cryptographic primitives provided by runtime environment +- Fail fast on invalid signatures +- Do not log sensitive data + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Event Type Processing +Supported events: +- Payment Successful: Update subscription to active, record transaction, grant entitlements +- Payment Failed: Record failure, keep subscription inactive, notify downstream systems if needed +- Refunded: Record refund, adjust subscription period or revoke entitlements + +Processing steps: +- Extract event type and associated IDs +- Load existing subscription and user context +- Apply state transitions deterministically +- Persist audit trail entries + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) + +### Subscription Status Updates and Entitlements +Actions: +- Update subscription table fields (status, period start/end, last paid at) +- Reconcile entitlements to match subscription state +- Handle proration or adjustments for refunds + +Patterns: +- Transactional updates to ensure consistency +- Backoff and retry for external calls +- Idempotent writes keyed by event IDs + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Database Synchronization Patterns +Guidelines: +- Use upserts keyed by PayMongo IDs to maintain idempotency +- Maintain separate tables for transactions, subscriptions, and refunds +- Keep an audit log for all changes triggered by webhooks +- Avoid long-running operations inside the webhook handler; offload heavy work to background jobs when possible + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Error Handling Strategies +Approach: +- Distinguish between client errors (invalid signature, malformed payload) and server errors (database failures) +- For transient errors, return 5xx to trigger PayMongo retries +- For permanent errors, return 200 after persisting failure details to allow manual review +- Include correlation IDs in logs for traceability + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Idempotency and Retry Mechanisms +Mechanisms: +- Store processed event IDs and skip duplicates +- Use atomic checks before applying state changes +- Implement exponential backoff for downstream service calls +- Provide a reconciliation job to detect missed or partial updates + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Dependency Analysis +The webhook function depends on shared HTTP utilities and entitlement management, and may coordinate with billing logic. + +```mermaid +graph LR +PMW["paymongo-webhook/index.ts"] --> HTTP["functions/_shared/http.ts"] +PMW --> ENT["functions/_shared/entitlement.ts"] +PMW --> BILL["src/lib/billing.js"] +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) + +## Performance Considerations +- Keep webhook processing minimal and synchronous to respond quickly to PayMongo +- Offload heavy tasks to background workers or queues +- Cache frequently accessed configuration (e.g., public keys) securely +- Batch database writes when feasible +- Monitor latency and error rates to tune timeouts and retries + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Signature mismatch: Verify secret configuration and header names; ensure raw body is used for verification +- Duplicate processing: Check idempotency store for event IDs; investigate race conditions +- Subscription drift: Run reconciliation jobs comparing PayMongo state with local records +- Timeouts: Reduce processing time; move non-critical work out of the handler +- Logging gaps: Add correlation IDs and structured logs for each step + +Operational tips: +- Inspect recent webhook deliveries and responses +- Replay failed events safely using stored payloads and event IDs +- Validate environment variables and secrets rotation procedures + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +The PayMongo webhook handler implements secure request validation, robust event routing, and consistent subscription and entitlement updates. By emphasizing idempotency, clear error handling, and efficient database synchronization, the system ensures reliable financial event processing while maintaining security and performance. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Webhook Payload Structures +Typical fields present in PayMongo webhook payloads: +- Event metadata: event ID, type, timestamp +- Resource identifiers: charge ID, invoice ID, subscription ID +- Financial details: amount, currency, status, refund information +- Customer references: customer ID, email, metadata + +Use these fields to: +- Identify the event type and route processing +- Correlate with local subscription and transaction records +- Populate audit logs and reconciliation reports + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +### Security Checklist +- Require HTTPS and validate Content-Type +- Verify HMAC signature using the correct algorithm and secret +- Enforce time-window checks to prevent replay attacks +- Sanitize inputs and avoid logging sensitive data +- Rotate secrets regularly and restrict access to configuration + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayPal Order Capture Flow.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayPal Order Capture Flow.md new file mode 100644 index 0000000..965f40f --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayPal Order Capture Flow.md @@ -0,0 +1,332 @@ +# PayPal Order Capture Flow + + +**Referenced Files in This Document** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document describes the end-to-end PayPal order capture workflow implemented in the project. It covers order creation, client-side approval, server-side capture, webhook-driven fulfillment, and refund handling. The flow emphasizes secure API calls to PayPal, robust state management, amount validation, error recovery, and clear user feedback. + +## Project Structure +The PayPal integration is implemented as Supabase Edge Functions with shared utilities and database migrations for fulfillment tracking. + +```mermaid +graph TB +subgraph "Client" +FE["Frontend App"] +end +subgraph "Supabase Edge Functions" +CPO["create-paypal-order/index.ts"] +CAP["capture-paypal-order/index.ts"] +WEBHOOK["paypal-webhook/index.ts"] +SHARED_PAYPAL["shared/paypal.ts"] +RUNTIME["shared/paypal-runtime.ts"] +end +subgraph "PayPal" +PP_API["PayPal Orders API"] +end +subgraph "Database" +DB[(PostgreSQL)] +end +FE --> CPO +FE --> CAP +FE --> WEBHOOK +CPO --> SHARED_PAYPAL +CAP --> SHARED_PAYPAL +WEBHOOK --> SHARED_PAYPAL +SHARED_PAYPAL --> RUNTIME +SHARED_PAYPAL --> PP_API +CPO --> DB +CAP --> DB +WEBHOOK --> DB +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Create Order Function: Creates a PayPal order on behalf of the client after validating request parameters and amounts. Returns an order ID for client approval. +- Capture Order Function: Captures an approved PayPal order and records fulfillment status in the database. +- Webhook Handler: Receives asynchronous events from PayPal (e.g., payment completions), reconciles state, and triggers fulfillment if needed. +- Shared PayPal Utilities: Encapsulates HTTP calls to PayPal, token management, and common response/error handling. +- Runtime Helpers: Provides environment configuration and runtime helpers used by PayPal utilities. +- Database Schema: Defines tables for orders, captures, and fulfillment records. + +Key responsibilities: +- Validate and normalize amounts before creating or capturing orders. +- Ensure idempotency and safe retries for capture and webhook processing. +- Maintain consistent order state across client, server, and PayPal. + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +The high-level sequence from order initiation to final capture includes client actions, server orchestration, PayPal interactions, and database updates. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant CreateOrder as "create-paypal-order" +participant PayPal as "PayPal Orders API" +participant Capture as "capture-paypal-order" +participant Webhook as "paypal-webhook" +participant DB as "Database" +Client->>CreateOrder : "Create order request
with items and total" +CreateOrder->>DB : "Persist pending order" +CreateOrder->>PayPal : "POST /v2/checkout/orders" +PayPal-->>CreateOrder : "Order ID + links" +CreateOrder-->>Client : "Order ID" +Client->>Client : "User approves via PayPal UI" +Client->>Capture : "Capture request with order ID" +Capture->>PayPal : "POST /v2/checkout/orders/{id}/capture" +PayPal-->>Capture : "Capture result" +Capture->>DB : "Record capture and update status" +Capture-->>Client : "Success or error" +PayPal-->>Webhook : "Async event (payment completed)" +Webhook->>DB : "Reconcile and mark fulfilled" +Webhook-->>PayPal : "200 OK" +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Create Order Endpoint +Purpose: +- Accepts client order details (items, currency, total). +- Validates inputs and amounts. +- Creates a PayPal order and persists a pending record. +- Returns the PayPal order ID to the client for approval. + +Key behaviors: +- Input validation: non-empty items, positive totals, supported currency codes. +- Amount normalization: ensure correct decimal precision and currency formatting. +- Idempotent order creation: avoid duplicate orders when clients retry. +- Error mapping: translate PayPal errors into user-friendly messages. + +```mermaid +flowchart TD +Start(["Receive create order request"]) --> Validate["Validate inputs and amounts"] +Validate --> Valid{"Valid?"} +Valid --> |No| ReturnError["Return validation error"] +Valid --> |Yes| Persist["Persist pending order in DB"] +Persist --> CallPP["Call PayPal Orders API to create order"] +CallPP --> PPSuccess{"PayPal success?"} +PPSuccess --> |No| MapErr["Map PayPal error to user message"] +MapErr --> ReturnError +PPSuccess --> |Yes| ReturnID["Return PayPal order ID"] +ReturnID --> End(["Done"]) +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Capture Order Endpoint +Purpose: +- Captures an approved PayPal order. +- Updates local order state to captured/paid. +- Ensures idempotency and handles partial captures if applicable. + +Key behaviors: +- Verify order exists and is in an approvable state. +- Call PayPal capture endpoint with the order ID. +- Record capture metadata and timestamps. +- Return confirmation to the client and trigger downstream fulfillment. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Capture as "capture-paypal-order" +participant PayPal as "PayPal Orders API" +participant DB as "Database" +Client->>Capture : "Capture(orderId)" +Capture->>DB : "Load order and validate state" +Capture->>PayPal : "POST /v2/checkout/orders/{id}/capture" +PayPal-->>Capture : "Capture result" +Capture->>DB : "Update order status and log capture" +Capture-->>Client : "Confirmation or error" +``` + +**Diagram sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### PayPal Webhook Handler +Purpose: +- Receives asynchronous events from PayPal (e.g., payments completed). +- Reconciles order state and marks fulfillment complete. +- Supports idempotent processing using event IDs. + +Key behaviors: +- Verify webhook signature and payload integrity. +- Parse event type and associated order ID. +- Update database records and trigger fulfillment logic. +- Respond with appropriate status codes to acknowledge receipt. + +```mermaid +flowchart TD +WStart(["Webhook received"]) --> Verify["Verify signature and parse payload"] +Verify --> EventType{"Event type?"} +EventType --> |Payment Completed| LoadOrder["Load order by PayPal order ID"] +LoadOrder --> UpdateState["Update order to fulfilled"] +UpdateState --> AckOK["Return 200 OK"] +EventType --> |Other Event| HandleOther["Handle other events"] +HandleOther --> AckOK +EventType --> |Invalid| Reject["Return 4xx error"] +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Shared PayPal Utilities and Runtime +Responsibilities: +- Encapsulate HTTP requests to PayPal endpoints. +- Manage access tokens and headers securely. +- Normalize responses and map errors consistently. +- Provide helper functions for amount formatting and validation. + +Runtime helpers: +- Load environment variables for credentials and base URLs. +- Provide logging and tracing hooks for debugging. + +**Section sources** +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +### Database Schema for Fulfillment +Tables and relationships: +- Orders: stores PayPal order ID, client reference, amounts, currency, and status. +- Captures: logs capture attempts, results, and timestamps. +- Fulfillments: tracks completion of business-side fulfillment tied to orders. + +Constraints and indexes: +- Unique constraints on PayPal order IDs to prevent duplicates. +- Indexes on order IDs and statuses for efficient queries. + +**Section sources** +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +The following diagram shows how components depend on each other and external services. + +```mermaid +graph LR +Create["create-paypal-order/index.ts"] --> Shared["shared/paypal.ts"] +Capture["capture-paypal-order/index.ts"] --> Shared +Webhook["paypal-webhook/index.ts"] --> Shared +Shared --> Runtime["shared/paypal-runtime.ts"] +Shared --> PayPal["PayPal Orders API"] +Create --> DB["Database"] +Capture --> DB +Webhook --> DB +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Minimize network calls: cache PayPal access tokens where appropriate and reuse connections. +- Use idempotency keys for create and capture operations to safely handle retries. +- Batch database writes when possible and keep transaction scopes small. +- Add timeouts and circuit breakers around PayPal API calls to prevent cascading failures. +- Log only necessary fields; avoid sensitive data in logs. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid amount or currency: ensure amounts are positive and formatted correctly per currency rules. +- Order not found or already captured: verify order state before capture; implement idempotent checks. +- Webhook signature verification failure: confirm secret configuration and payload integrity. +- Network errors from PayPal: implement retries with exponential backoff and surface actionable errors to users. +- Partial captures: handle scenarios where full capture fails but partial succeeds; reconcile amounts and notify users. + +Operational tips: +- Inspect database records for order lifecycle states and capture logs. +- Correlate PayPal event IDs with local order IDs for auditability. +- Use structured logging to trace requests across create, capture, and webhook flows. + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Conclusion +The PayPal order capture flow integrates client approvals with server-side orchestration, robust validation, and reliable state management. By leveraging shared utilities, idempotent operations, and webhook reconciliation, the system ensures secure transactions, accurate amount handling, and resilient error recovery. Proper logging and database tracking provide visibility into the entire lifecycle from order creation through capture and fulfillment. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayPal Webhook Handler.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayPal Webhook Handler.md new file mode 100644 index 0000000..bed0941 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Billing Webhook Handlers/PayPal Webhook Handler.md @@ -0,0 +1,417 @@ +# PayPal Webhook Handler + + +**Referenced Files in This Document** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the PayPal webhook handler and related billing flows. It covers: +- Supported PayPal event types (e.g., payment capture completion, subscription lifecycle events) +- Signature verification using PayPal’s certificate-based authentication +- Order capture confirmation flow +- Subscription lifecycle management +- Payload examples, state transitions, and database updates +- PayPal-specific error handling, webhook versioning, and debugging techniques + +The implementation is provided as Supabase Edge Functions with shared utilities for PayPal integration. + +## Project Structure +Key files involved in PayPal webhooks and fulfillment: +- supabase/functions/paypal-webhook/index.ts: Entry point for receiving and processing PayPal webhooks +- supabase/functions/_shared/paypal.ts: PayPal client helpers and request/response shaping +- supabase/functions/_shared/paypal-runtime.ts: Runtime configuration and environment access for PayPal +- supabase/functions/_shared/paypal.test.ts: Tests for PayPal utilities +- supabase/functions/capture-paypal-order/index.ts: Captures a previously created PayPal order +- supabase/functions/create-checkout/index.ts: Creates a PayPal checkout session or order +- supabase/functions/cancel-subscription/index.ts: Cancels an existing PayPal subscription +- supabase/migrations/002_paypal_fulfillment.sql: Database schema for tracking PayPal fulfillments and subscriptions + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +PW["paypal-webhook/index.ts"] +CAP["capture-paypal-order/index.ts"] +CHK["create-checkout/index.ts"] +CANCEL["cancel-subscription/index.ts"] +SH_PAYPAL["_shared/paypal.ts"] +SH_RT["_shared/paypal-runtime.ts"] +end +subgraph "Database" +DB[(PostgreSQL)] +end +subgraph "PayPal API" +PP["PayPal REST API"] +end +PW --> SH_PAYPAL +PW --> SH_RT +PW --> DB +CAP --> SH_PAYPAL +CAP --> SH_RT +CAP --> DB +CHK --> SH_PAYPAL +CHK --> SH_RT +CANCEL --> SH_PAYPAL +CANCEL --> SH_RT +PW --> PP +CAP --> PP +CHK --> PP +CANCEL --> PP +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- PayPal Webhook Handler: Receives webhook events, verifies authenticity, routes to handlers by event type, persists audit records, and triggers fulfillment logic. +- PayPal Client Utilities: Encapsulates HTTP calls to PayPal APIs, token acquisition, and response parsing. +- Runtime Configuration: Loads environment variables such as client ID, secret, and sandbox toggles. +- Fulfillment Migrations: Defines tables for orders, captures, subscriptions, and status tracking. + +Responsibilities: +- Authentication and signature verification against PayPal certificates +- Idempotent processing of webhook events +- State transitions for orders and subscriptions +- Error reporting and retry guidance + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +End-to-end flow from PayPal to your system: + +```mermaid +sequenceDiagram +participant P as "PayPal" +participant F as "paypal-webhook/index.ts" +participant V as "paypal.ts" +participant R as "paypal-runtime.ts" +participant D as "Database" +P->>F : "HTTP POST /paypal-webhook" +F->>R : "Load config (client id, secret, env)" +F->>V : "Verify webhook signature" +V-->>F : "Verified or error" +alt "Signature valid" +F->>F : "Parse event_type and resource" +F->>D : "Persist raw payload and metadata" +alt "Event : PAYMENT.CAPTURE.COMPLETED" +F->>D : "Update order/capture status" +else "Event : BILLING.SUBSCRIPTION.*" +F->>D : "Transition subscription state" +end +F-->>P : "200 OK" +else "Signature invalid" +F-->>P : "401 Unauthorized" +end +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### PayPal Webhook Handler +Purpose: +- Accepts incoming webhook requests +- Verifies authenticity using PayPal’s certificate chain +- Routes events to specific handlers based on event_type +- Persists audit logs and performs idempotent updates +- Returns appropriate HTTP status codes + +Key behaviors: +- Signature verification using PayPal-provided certificates +- Event routing by event_type (e.g., PAYMENT.CAPTURE.COMPLETED, BILLING.SUBSCRIPTION.CREATED/ACTIVE/CANCELLED) +- Deduplication via event_id or resource_id +- Database updates for orders and subscriptions + +```mermaid +flowchart TD +Start(["Receive webhook"]) --> Verify["Verify signature with PayPal certs"] +Verify --> Valid{"Valid?"} +Valid --> |No| Reject["Return 401"] +Valid --> |Yes| Parse["Parse event_type and resource"] +Parse --> Persist["Persist payload and metadata"] +Persist --> Route{"Event Type"} +Route --> |PAYMENT.CAPTURE.COMPLETED| CaptureHandler["Handle capture completion"] +Route --> |BILLING.SUBSCRIPTION.CREATED| SubCreated["Create subscription record"] +Route --> |BILLING.SUBSCRIPTION.ACTIVE| SubActive["Activate subscription"] +Route --> |BILLING.SUBSCRIPTION.CANCELLED| SubCancelled["Cancel subscription"] +CaptureHandler --> UpdateDB["Update order/capture status"] +SubCreated --> UpdateDB +SubActive --> UpdateDB +SubCancelled --> UpdateDB +UpdateDB --> Done(["Return 200 OK"]) +Reject --> End(["Exit"]) +Done --> End +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### PayPal Client Utilities +Purpose: +- Provides functions to call PayPal APIs (orders, captures, subscriptions) +- Handles token acquisition and request signing +- Normalizes responses into internal models + +Key responsibilities: +- Token retrieval and caching +- Constructing authenticated requests +- Parsing and validating PayPal responses +- Mapping PayPal fields to internal entities + +```mermaid +classDiagram +class PayPalClient { ++getAccessToken() ++createOrder(params) ++captureOrder(orderId) ++getSubscription(subscriptionId) ++cancelSubscription(subscriptionId) +} +class PayPalRuntime { ++getClientId() ++getSecret() ++isSandbox() +} +PayPalClient --> PayPalRuntime : "uses" +``` + +**Diagram sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +### Order Capture Confirmation +Purpose: +- Confirms and finalizes a PayPal order after user authorization +- Updates internal order state to captured and fulfills entitlements + +Flow: +- Frontend calls create-checkout to obtain an order ID +- After user approves, frontend invokes capture-paypal-order +- Backend verifies order state and captures funds +- On success, backend updates database and grants access + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant CHK as "create-checkout/index.ts" +participant CAP as "capture-paypal-order/index.ts" +participant PP as "PayPal API" +participant DB as "Database" +FE->>CHK : "Create checkout (order)" +CHK->>PP : "Create order" +PP-->>CHK : "Order ID" +CHK-->>FE : "Order ID" +FE->>CAP : "Capture order (order ID)" +CAP->>PP : "Capture order" +PP-->>CAP : "Capture result" +CAP->>DB : "Update order status to captured" +CAP-->>FE : "Success" +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### Subscription Lifecycle Management +Supported events: +- BILLING.SUBSCRIPTION.CREATED +- BILLING.SUBSCRIPTION.ACTIVE +- BILLING.SUBSCRIPTION.CANCELLED +- Additional lifecycle events as needed (e.g., EXPIRED, SUSPENDED) + +State transitions: +- Created -> Active upon successful activation +- Active -> Cancelled when cancellation occurs +- Active -> Expired if subscription lapses + +```mermaid +stateDiagram-v2 +[*] --> Pending +Pending --> Active : "BILLING.SUBSCRIPTION.ACTIVE" +Pending --> Cancelled : "BILLING.SUBSCRIPTION.CANCELLED" +Active --> Cancelled : "BILLING.SUBSCRIPTION.CANCELLED" +Active --> Expired : "BILLING.SUBSCRIPTION.EXPIRED" +Cancelled --> [*] +Expired --> [*] +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Database Schema and Updates +Tables typically include: +- Orders: order_id, paypal_order_id, status, amount, currency, created_at, updated_at +- Captures: capture_id, order_id, status, amount, currency, captured_at +- Subscriptions: subscription_id, paypal_subscription_id, status, plan_id, billing_cycle, next_billing_date, created_at, updated_at +- WebhookAudit: event_id, event_type, resource_id, raw_payload, processed_at, status + +Updates: +- On PAYMENT.CAPTURE.COMPLETED: mark order as captured, insert capture record +- On BILLING.SUBSCRIPTION.*: update subscription status and timestamps +- Always persist raw payloads for auditing and replay + +**Section sources** +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +Internal dependencies: +- paypal-webhook depends on paypal utilities and runtime configuration +- capture-paypal-order and cancel-subscription depend on paypal utilities and runtime configuration +- All components interact with the database through Supabase client + +External dependencies: +- PayPal REST API endpoints for orders, captures, subscriptions +- PayPal certificate endpoints for signature verification + +```mermaid +graph LR +PW["paypal-webhook/index.ts"] --> SH_PAYPAL["_shared/paypal.ts"] +PW --> SH_RT["_shared/paypal-runtime.ts"] +CAP["capture-paypal-order/index.ts"] --> SH_PAYPAL +CAP --> SH_RT +CANCEL["cancel-subscription/index.ts"] --> SH_PAYPAL +CANCEL --> SH_RT +PW --> DB["Database"] +CAP --> DB +CANCEL --> DB +PW --> PP["PayPal API"] +CAP --> PP +CANCEL --> PP +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Idempotency: Use event_id or resource_id to avoid duplicate processing +- Minimal payload persistence: Store only necessary fields; archive raw payloads separately if large +- Connection pooling: Ensure database connections are reused within function execution +- Timeout handling: PayPal webhooks may be delayed; implement retries at the platform level +- Logging: Keep structured logs for correlation IDs and event types + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Signature verification failures: + - Ensure correct PayPal certificate URLs and network access + - Validate environment variables for client ID and secret + - Check time skew and TLS settings +- Duplicate events: + - Implement deduplication using event_id or resource_id + - Maintain processed event registry +- Missing or incorrect fields: + - Validate required fields before processing + - Log malformed payloads for review +- Subscription state mismatches: + - Reconcile local state with PayPal subscription details + - Use explicit transitions and guard conditions + +Debugging techniques: +- Enable verbose logging for webhook payloads and responses +- Use correlation IDs across functions and database records +- Replay failed events using stored raw payloads +- Monitor PayPal dashboard for delivery status and errors + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +## Conclusion +The PayPal webhook handler integrates securely with PayPal’s API, verifying signatures and managing order captures and subscription lifecycles. By enforcing idempotency, robust error handling, and clear state transitions, the system ensures reliable fulfillment and consistent database state. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Webhook Event Types and Handling +- PAYMENT.CAPTURE.COMPLETED: Finalize order capture and grant entitlements +- BILLING.SUBSCRIPTION.CREATED: Initialize subscription record +- BILLING.SUBSCRIPTION.ACTIVE: Activate subscription and enable features +- BILLING.SUBSCRIPTION.CANCELLED: Disable features and update status + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Webhook Versioning +- Track webhook versions in metadata +- Support backward-compatible parsing for older payloads +- Migrate handlers gradually when breaking changes occur + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Checkout & Subscription Management.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Checkout & Subscription Management.md new file mode 100644 index 0000000..711a229 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Checkout & Subscription Management.md @@ -0,0 +1,363 @@ +# Checkout & Subscription Management + + +**Referenced Files in This Document** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the end-to-end checkout and subscription management flows, including: +- Creating a checkout session +- Pricing calculations and discount application +- Payment completion via webhook +- Updating user entitlements after successful payment +- Subscription cancellation workflows +- Refund processing considerations +- Account state transitions and error handling for payment failures + +The goal is to provide both high-level understanding and code-level details for developers integrating or maintaining billing features. + +## Project Structure +Billing-related functionality spans serverless functions (Supabase Edge Functions), client-side libraries, and design documentation: +- Serverless functions handle checkout creation, webhooks, and subscription lifecycle events +- Client libraries encapsulate pricing, billing orchestration, and entitlement logic +- Design docs outline architecture and integration points with payment providers + +```mermaid +graph TB +subgraph "Client" +A["billing.js"] +B["entitlement.js"] +C["pricing.js"] +end +subgraph "Edge Functions" +D["create-checkout/index.ts"] +E["paymongo-webhook/index.ts"] +F["cancel-subscription/index.ts"] +end +subgraph "External Providers" +G["PayMongo"] +end +A --> D +D --> G +G --> E +E --> B +A --> C +A --> B +F --> B +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) + +**Section sources** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Checkout Creation Function: Creates a payment session with validated parameters, computes totals, applies discounts, and returns a redirect URL to the provider. +- Webhook Handler: Verifies signatures, processes payment events, updates order/subscription records, and triggers entitlement updates. +- Billing Library: Orchestrates checkout calls, manages session metadata, and coordinates post-payment actions on the client. +- Entitlement Library: Evaluates and updates user access based on active subscriptions and one-time purchases. +- Pricing Library: Provides base prices, tiers, and discount rules used during checkout calculation. + +Key responsibilities: +- Input validation and idempotency +- Secure signature verification +- Accurate price computation and currency handling +- Reliable state synchronization between provider, backend, and client +- Clear error propagation and retry strategies + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) + +## Architecture Overview +The checkout flow integrates client orchestration, serverless checkout creation, external payment processing, and webhook-driven fulfillment. + +```mermaid +sequenceDiagram +participant UI as "Client App" +participant Billing as "billing.js" +participant Checkout as "create-checkout/index.ts" +participant Provider as "PayMongo" +participant Webhook as "paymongo-webhook/index.ts" +participant Entitle as "entitlement.js" +UI->>Billing : "Initiate checkout with items, discounts, user" +Billing->>Checkout : "Create checkout session" +Checkout->>Checkout : "Validate params
Compute totals
Apply discounts" +Checkout->>Provider : "Create payment session" +Provider-->>Checkout : "Session URL" +Checkout-->>Billing : "Redirect URL + session metadata" +Billing-->>UI : "Redirect to provider" +Note over UI,Provider : "User completes payment" +Provider->>Webhook : "Payment event" +Webhook->>Webhook : "Verify signature
Idempotent processing" +Webhook->>Entitle : "Update entitlements" +Entitle-->>Webhook : "Result" +Webhook-->>UI : "Fulfillment complete" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +## Detailed Component Analysis + +### Checkout Session Creation +Responsibilities: +- Validate inputs (user identity, items, quantities, discount codes) +- Compute line-item totals and apply discounts deterministically +- Create a provider session with stable metadata for reconciliation +- Return a secure redirect URL to the provider’s hosted checkout + +Important behaviors: +- Idempotency keys prevent duplicate sessions +- Currency and rounding handled consistently +- Metadata includes user ID, plan/tier, and order identifiers for webhook matching + +```mermaid +flowchart TD +Start(["Start"]) --> Validate["Validate request parameters"] +Validate --> Valid{"Valid?"} +Valid -- "No" --> Err["Return validation error"] +Valid -- "Yes" --> Calc["Calculate totals and discounts"] +Calc --> Create["Create provider session with metadata"] +Create --> Redirect["Return redirect URL"] +Redirect --> End(["End"]) +Err --> End +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [pricing.js](file://src/lib/pricing.js) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [pricing.js](file://src/lib/pricing.js) + +### Pricing Calculations and Discount Application +Responsibilities: +- Resolve base prices by tier or item SKU +- Apply percentage or fixed discounts with precedence rules +- Enforce minimums, caps, and tax handling if applicable +- Ensure deterministic results across client and server + +Best practices: +- Always compute totals server-side +- Use integer cents or smallest currency unit +- Log discount breakdowns for auditability + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) + +### Payment Completion and Fulfillment +Responsibilities: +- Receive and verify webhook signatures +- Process only confirmed payment events +- Update internal records (orders/subscriptions) +- Trigger entitlement updates and notify clients + +Error handling: +- Reject unknown events or invalid payloads +- Implement idempotent processing using event IDs +- Retry failed operations safely + +```mermaid +sequenceDiagram +participant Provider as "PayMongo" +participant Webhook as "paymongo-webhook/index.ts" +participant DB as "Database" +participant Entitle as "entitlement.js" +Provider->>Webhook : "Event payload" +Webhook->>Webhook : "Verify signature" +Webhook->>DB : "Upsert order/subscription" +Webhook->>Entitle : "Grant entitlements" +Entitle-->>Webhook : "Success/Failure" +Webhook-->>Provider : "200 OK" +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +### User Entitlement Updates +Responsibilities: +- Evaluate current subscriptions and one-time purchases +- Grant or revoke access to features based on effective dates and status +- Persist entitlement state and propagate changes to clients + +State transitions: +- Active -> Expired (non-renewal) +- Active -> Cancelled (end-of-period) +- Pending -> Active (payment success) +- Failed -> Inactive (payment failure) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) + +### Subscription Cancellation Workflow +Responsibilities: +- Accept cancellation requests from authenticated users +- Determine cancellation timing (immediate vs period-end) +- Update subscription status and schedule final billing +- Revoke or adjust entitlements per policy + +```mermaid +flowchart TD +Req(["Cancel Request"]) --> Auth["Authenticate user"] +Auth --> Lookup["Lookup subscription"] +Lookup --> Policy{"Cancellation policy"} +Policy -- "Immediate" --> Revoke["Revoke entitlements now"] +Policy -- "Period-end" --> Schedule["Schedule revocation"] +Revoke --> Confirm["Confirm cancellation"] +Schedule --> Confirm +Confirm --> End(["Done"]) +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +### Refund Processing +Responsibilities: +- Handle refund events from the provider +- Reverse charges and adjust entitlements accordingly +- Maintain audit logs and reconcile discrepancies + +Considerations: +- Partial vs full refunds +- Time windows for eligibility +- Customer communication and support workflows + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Client Orchestration (billing.js) +Responsibilities: +- Build checkout payloads with items, discounts, and user context +- Call the checkout creation function and handle redirects +- Listen for fulfillment signals and refresh entitlements +- Surface errors and guide users through retries + +```mermaid +sequenceDiagram +participant UI as "Client UI" +participant Billing as "billing.js" +participant Checkout as "create-checkout/index.ts" +participant Provider as "PayMongo" +participant Webhook as "paymongo-webhook/index.ts" +UI->>Billing : "Select plan/items, enter discount" +Billing->>Checkout : "Create checkout session" +Checkout-->>Billing : "Redirect URL" +Billing->>UI : "Navigate to provider" +Provider-->>Webhook : "Payment event" +Webhook-->>Billing : "Fulfillment signal" +Billing-->>UI : "Show success and updated features" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) + +## Dependency Analysis +High-level dependencies among components: +- billing.js depends on create-checkout function and pricing/entitlement modules +- paymongo-webhook depends on entitlement updates and database writes +- cancel-subscription depends on entitlement adjustments and subscription records + +```mermaid +graph LR +Billing["billing.js"] --> Checkout["create-checkout/index.ts"] +Billing --> Pricing["pricing.js"] +Billing --> Entitle["entitlement.js"] +Webhook["paymongo-webhook/index.ts"] --> Entitle +Cancel["cancel-subscription/index.ts"] --> Entitle +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) + +## Performance Considerations +- Keep checkout creation lightweight; defer heavy computations to server-side +- Cache static pricing data where safe to do so +- Use idempotency keys to avoid redundant provider calls +- Batch entitlement updates when possible +- Monitor webhook latency and implement backoff for retries + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid or missing parameters in checkout requests: validate early and return clear errors +- Signature verification failures in webhooks: ensure secret configuration and exact payload hashing +- Duplicate events: rely on idempotency keys and deduplicate by event ID +- Entitlement mismatches: reconcile provider state with local records and re-run fulfillment +- Payment failures: surface actionable messages and allow retry with updated payment method + +Operational checks: +- Verify webhook endpoints are reachable and returning 2xx +- Inspect logs for signature mismatches and malformed payloads +- Audit discount application logs for unexpected totals +- Confirm subscription status transitions align with provider events + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +## Conclusion +The checkout and subscription system combines robust server-side validation, precise pricing and discount logic, reliable webhook processing, and consistent entitlement management. By following the documented flows and best practices, teams can deliver a resilient billing experience that scales and remains auditable. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Data Export Utilities.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Data Export Utilities.md new file mode 100644 index 0000000..c382866 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Data Export Utilities.md @@ -0,0 +1,283 @@ +# Data Export Utilities + + +**Referenced Files in This Document** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [storage.js](file://src/lib/storage.js) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the data export utilities with a focus on the MessagePack download functionality. It covers how exports are generated, serialized, and delivered to users, including security measures for access control, file size limitations, and format specifications. It also provides examples for triggering exports, handling large datasets, and managing download expiration. + +## Project Structure +The export feature spans serverless functions (Supabase Edge Functions), client-side libraries, and a helper script: +- Server-side export endpoint: Supabase Edge Function that generates and serves the export. +- Client-side helpers: Libraries for CSV generation, sharing, storage, and Supabase client configuration. +- Helper script: A Python utility for generating MessagePack content locally or in CI. + +```mermaid +graph TB +subgraph "Client" +UI["User Interface"] +ShareLib["share.js"] +CsvLib["csv.js"] +StorageLib["storage.js"] +SupabaseLib["supabase.js"] +end +subgraph "Serverless" +EdgeFn["download-message-pack/index.ts"] +end +subgraph "Utilities" +PyGen["generate_message_pack.py"] +end +UI --> ShareLib +UI --> CsvLib +UI --> StorageLib +UI --> SupabaseLib +ShareLib --> EdgeFn +CsvLib --> UI +StorageLib --> UI +PyGen --> UI +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [storage.js](file://src/lib/storage.js) +- [supabase.js](file://src/lib/supabase.js) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [storage.js](file://src/lib/storage.js) +- [supabase.js](file://src/lib/supabase.js) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +## Core Components +- MessagePack download function: The serverless endpoint responsible for validating requests, assembling export data, serializing it into MessagePack, and returning a downloadable response with appropriate headers and expiration controls. +- Client-side share library: Orchestrates export triggers, manages temporary links, and handles user feedback. +- CSV library: Provides an alternative export path for tabular data when needed. +- Storage library: Manages local caching and persistence of export metadata or artifacts as required by the app. +- Supabase client: Configures authentication and network calls to the serverless function. +- Python generator: Utility to produce MessagePack payloads for testing or offline workflows. + +Key responsibilities: +- Security: Validate identity and permissions before generating any export. +- Serialization: Produce compact, deterministic MessagePack output; optionally provide CSV fallbacks. +- Download management: Set correct Content-Type, Content-Disposition, and expiration behavior. +- Size limits: Enforce maximum payload sizes to protect server resources and ensure reliable delivery. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [share.js](file://src/lib/share.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) +- [supabase.js](file://src/lib/supabase.js) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +## Architecture Overview +The export flow is designed around a secure serverless endpoint that produces a MessagePack archive. Clients request an export via authenticated calls, receive a response with proper headers, and manage expiration at the application layer if necessary. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "App UI" +participant Share as "share.js" +participant SB as "supabase.js" +participant Edge as "download-message-pack/index.ts" +User->>UI : "Export data" +UI->>Share : "Trigger export" +Share->>SB : "Call /functions/download-message-pack" +SB->>Edge : "HTTP request with auth" +Edge->>Edge : "Validate session/permissions" +Edge->>Edge : "Assemble dataset" +Edge->>Edge : "Serialize to MessagePack" +Edge-->>SB : "Response with headers and payload" +SB-->>Share : "Downloadable response" +Share-->>UI : "Handle success/failure" +UI-->>User : "Show status and file" +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### MessagePack Download Endpoint +Responsibilities: +- Authentication and authorization checks. +- Input validation and rate limiting considerations. +- Dataset assembly from internal state or external services. +- MessagePack serialization and optional compression. +- Response construction with correct MIME type and filename. +- Expiration policy enforcement and error handling. + +Security measures: +- Require valid session tokens. +- Scope exports to the requesting user’s data only. +- Validate all inputs and reject malformed requests. +- Enforce maximum payload size to prevent abuse. + +File generation process: +- Build structured data objects representing the export. +- Serialize using a MessagePack encoder. +- Attach headers: Content-Type for MessagePack, Content-Disposition for filename, and cache-control directives. + +Download link management: +- If returning a direct blob, set appropriate headers so browsers can save the file. +- If returning a signed URL, include expiration time and validate on subsequent downloads. + +Error handling: +- Return standardized error responses for invalid sessions, missing data, and size limit violations. +- Log errors securely without leaking sensitive information. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) + +### Client-Side Share Library +Responsibilities: +- Orchestrate export triggers across the app. +- Manage temporary links and retry logic. +- Provide user feedback and progress indicators. +- Coordinate with storage for caching export metadata. + +Usage patterns: +- Trigger export on user action. +- Handle success by saving the file or updating UI. +- Handle failures by showing actionable messages and allowing retries. + +**Section sources** +- [share.js](file://src/lib/share.js) + +### CSV Export Library +Responsibilities: +- Convert arrays of records to CSV strings. +- Handle escaping, quoting, and encoding. +- Provide a fallback export format when MessagePack is not suitable. + +Integration points: +- Used by UI components for tabular data exports. +- Can be combined with storage to persist intermediate results. + +**Section sources** +- [csv.js](file://src/lib/csv.js) + +### Storage Library +Responsibilities: +- Persist export metadata and small artifacts locally. +- Manage cache lifetimes and cleanup. +- Support offline scenarios where applicable. + +Best practices: +- Avoid storing large binary files in local storage. +- Use structured keys and versioning for schema evolution. + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### Supabase Client Configuration +Responsibilities: +- Initialize the Supabase client with environment settings. +- Provide authenticated calls to serverless functions. +- Centralize error handling and retries. + +Configuration notes: +- Ensure correct project URL and anonymous/public keys. +- Enable token refresh and handle session expiry gracefully. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) + +### Python MessagePack Generator +Responsibilities: +- Generate MessagePack payloads for testing or CI. +- Validate schema and determinism of exported structures. +- Assist in performance benchmarking and regression tests. + +Usage: +- Run locally to produce sample archives. +- Integrate into test suites to assert export correctness. + +**Section sources** +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +## Dependency Analysis +The export feature has clear boundaries between client and server responsibilities. The serverless function depends on authentication and data assembly logic, while the client relies on shared libraries for orchestration and formatting. + +```mermaid +graph LR +Share["share.js"] --> Supabase["supabase.js"] +Share --> Storage["storage.js"] +Share --> Edge["download-message-pack/index.ts"] +Csv["csv.js"] --> UI["App UI"] +PyGen["generate_message_pack.py"] --> Test["Tests/CI"] +``` + +**Diagram sources** +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [storage.js](file://src/lib/storage.js) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [csv.js](file://src/lib/csv.js) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +**Section sources** +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [storage.js](file://src/lib/storage.js) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [csv.js](file://src/lib/csv.js) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +## Performance Considerations +- Prefer MessagePack for compact, fast serialization over JSON for large datasets. +- Stream or chunk large exports when possible to reduce memory pressure. +- Enforce strict size limits on the server side to avoid timeouts. +- Cache frequently requested exports with short TTLs if safe. +- Use deterministic ordering and stable schemas to enable efficient diffs and caching. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: Verify session validity and token refresh logic. +- Permission denied: Ensure the exporting user has access to the requested data scope. +- Payload too large: Reduce dataset size, paginate, or split into multiple exports. +- Invalid MIME type: Confirm Content-Type header matches MessagePack. +- Missing filename: Check Content-Disposition header includes a valid filename. +- Expiration errors: Regenerate signed URLs or re-trigger the export within allowed windows. + +Operational tips: +- Add structured logging for failed exports without exposing sensitive data. +- Instrument client-side metrics for export duration and failure rates. +- Use the Python generator to reproduce problematic payloads in isolation. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +The data export utilities center on a secure, efficient MessagePack download endpoint with robust client-side orchestration. By enforcing strong access controls, setting clear size limits, and standardizing formats and headers, the system delivers reliable exports while maintaining performance and safety. For large datasets, consider pagination and splitting strategies, and use the provided tools to validate and test export behavior. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Edge Functions.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Edge Functions.md new file mode 100644 index 0000000..557712e --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Edge Functions/Edge Functions.md @@ -0,0 +1,413 @@ +# Edge Functions + + +**Referenced Files in This Document** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/config.toml](file://supabase/config.toml) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document describes the Supabase Edge Functions architecture for the project, focusing on serverless endpoints that power AI resume analysis, payment checkout creation, webhook handling for PayMongo and PayPal, and data export utilities. It explains request/response formats, integration patterns, authentication middleware, error handling strategies, rate limiting approaches, and security considerations. It also provides guidance on how to invoke functions from clients, validate parameters, and format responses consistently. + +## Project Structure +The Edge Functions are organized under supabase/functions with a shared utilities layer under _shared. Each function is a self-contained entry point implementing a specific responsibility: +- ai-proxy: Proxies requests to an AI provider for resume analysis. +- create-checkout: Creates payment checkouts via supported providers. +- paymongo-webhook: Handles PayMongo webhook events. +- paypal-webhook: Handles PayPal webhook events. +- capture-paypal-order: Captures PayPal orders after payment authorization. +- create-paypal-order: Creates PayPal orders for checkout flows. +- download-message-pack: Exports application messages as MessagePack. + +```mermaid +graph TB +subgraph "Edge Functions" +A["ai-proxy/index.ts"] +B["create-checkout/index.ts"] +C["paymongo-webhook/index.ts"] +D["paypal-webhook/index.ts"] +E["capture-paypal-order/index.ts"] +F["create-paypal-order/index.ts"] +G["download-message-pack/index.ts"] +end +subgraph "Shared Utilities" +H["_shared/http.ts"] +I["_shared/entitlement.ts"] +J["_shared/paypal.ts"] +K["_shared/paypal-runtime.ts"] +L["_shared/prompts.ts"] +end +A --> H +B --> H +C --> H +D --> H +E --> H +F --> H +G --> H +D --> J +E --> J +F --> J +F --> K +E --> K +A --> L +``` + +**Diagram sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [supabase/config.toml](file://supabase/config.toml) + +## Core Components +- HTTP utility: Centralized helpers for constructing responses, parsing JSON, and standardizing error shapes across functions. +- Entitlement helper: Validates user access and feature flags used by protected endpoints. +- PayPal SDK/runtime: Encapsulates PayPal API calls and runtime configuration for order creation and capture. +- Prompts: Shared prompt templates used by the AI proxy for resume analysis. + +Key responsibilities: +- Consistent response formatting (success/error envelopes). +- Centralized validation and error mapping. +- Secure credential management via environment variables. +- Reusable business logic for entitlement checks and payment operations. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Architecture Overview +The system follows a clear separation between function handlers and shared utilities: +- Handlers receive HTTP requests, validate inputs, enforce authentication/entitlements, call external services, and return standardized responses. +- Shared modules encapsulate cross-cutting concerns like HTTP response shaping, PayPal integrations, and entitlement checks. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Edge as "Supabase Edge Function" +participant Http as "_shared/http.ts" +participant Ent as "_shared/entitlement.ts" +participant Ext as "External Service" +Client->>Edge : "HTTP Request" +Edge->>Http : "Parse request and build context" +Edge->>Ent : "Validate entitlement/access" +alt "Authorized" +Edge->>Ext : "Call external service (AI/PayPal/Payment)" +Ext-->>Edge : "Response or Error" +Edge->>Http : "Format success/error envelope" +Http-->>Client : "Standardized Response" +else "Unauthorized" +Edge->>Http : "Return 401/403" +Http-->>Client : "Error Envelope" +end +``` + +**Diagram sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### AI Proxy Function (Resume Analysis) +Purpose: +- Accepts resume content and analysis prompts, forwards them to an AI provider, and returns structured analysis results. + +Request format: +- Method: POST +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: + - resume_text: string + - prompt_id: string (selects template from shared prompts) + - options: object (optional; e.g., tone, focus areas) + +Response format: +- Success: { status: "ok", result: object } +- Error: { status: "error", code: string, message: string } + +Integration pattern: +- Validates input using shared utilities. +- Loads prompt template from shared prompts. +- Calls AI provider with sanitized payload. +- Normalizes errors and returns consistent envelope. + +Security considerations: +- Validate and sanitize resume text length and characters. +- Rate limit per-user to prevent abuse. +- Redact sensitive data before sending to AI provider. + +Invocation example (conceptual): +- POST /functions/v1/ai-proxy with Authorization header and JSON body containing resume_text and prompt_id. + +**Section sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Create Checkout Function +Purpose: +- Creates a payment checkout session based on selected provider (PayMongo or PayPal). + +Request format: +- Method: POST +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: + - provider: "paymongo" | "paypal" + - amount: number + - currency: string + - metadata: object (optional; e.g., user_id, plan_id) + +Response format: +- Success: { status: "ok", checkout_url: string, id: string } +- Error: { status: "error", code: string, message: string } + +Integration pattern: +- Validates provider-specific parameters. +- Delegates to provider-specific logic (PayMongo or PayPal). +- Returns a secure checkout URL or order ID. + +Rate limiting: +- Apply per-user limits to prevent spammy checkout creation. + +**Section sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### PayMongo Webhook Handler +Purpose: +- Receives PayMongo webhook events, verifies signatures, updates subscription/payment state, and acknowledges receipt. + +Request format: +- Method: POST +- Headers: X-PayMongo-Signature +- Body: PayMongo event payload + +Processing steps: +- Verify signature using shared HTTP utilities. +- Parse event type and payload. +- Update internal state (e.g., subscription status, payment records). +- Return 200 OK upon successful processing. + +Error handling: +- Log invalid signatures and malformed payloads. +- Return appropriate HTTP status codes for retries. + +**Section sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal Webhook Handler +Purpose: +- Processes PayPal webhook events, validates signatures, reconciles payments, and updates entitlements. + +Request format: +- Method: POST +- Headers: Authorization-Authorization, Webhook-ID, Webhook-Signature +- Body: PayPal event payload + +Processing steps: +- Validate webhook signature and IDs. +- Handle event types (e.g., payment.capture.completed). +- Update order and user entitlements accordingly. +- Acknowledge with 200 OK. + +Error handling: +- Reject unknown or invalid events. +- Provide detailed error logs for debugging. + +**Section sources** +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Capture PayPal Order +Purpose: +- Captures an authorized PayPal order to finalize payment. + +Request format: +- Method: POST +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: + - order_id: string + +Response format: +- Success: { status: "ok", capture_id: string, amount: number } +- Error: { status: "error", code: string, message: string } + +Integration pattern: +- Uses PayPal runtime and SDK to capture the order. +- Updates local records and notifies client. + +**Section sources** +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Create PayPal Order +Purpose: +- Creates a PayPal order for checkout flows. + +Request format: +- Method: POST +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: + - amount: number + - currency: string + - metadata: object (optional) + +Response format: +- Success: { status: "ok", order_id: string, approve_url: string } +- Error: { status: "error", code: string, message: string } + +Integration pattern: +- Builds PayPal order payload using shared PayPal utilities. +- Returns approval URL for client redirection. + +**Section sources** +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Download Message Pack Utility +Purpose: +- Exports application messages as a MessagePack file for offline use or analytics. + +Request format: +- Method: GET +- Headers: Authorization (Bearer token) +- Query params: + - format: "msgpack" + - filters: optional (e.g., date range, categories) + +Response format: +- Success: Binary MessagePack stream +- Error: { status: "error", code: string, message: string } + +Security considerations: +- Ensure only authenticated users can download exports. +- Validate filter parameters to prevent excessive queries. + +**Section sources** +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Dependency Analysis +Functions rely on shared utilities for HTTP handling, entitlement checks, and PayPal integrations. The following diagram shows dependencies among functions and shared modules. + +```mermaid +graph LR +subgraph "Functions" +F1["ai-proxy/index.ts"] +F2["create-checkout/index.ts"] +F3["paymongo-webhook/index.ts"] +F4["paypal-webhook/index.ts"] +F5["capture-paypal-order/index.ts"] +F6["create-paypal-order/index.ts"] +F7["download-message-pack/index.ts"] +end +S1["_shared/http.ts"] +S2["_shared/entitlement.ts"] +S3["_shared/paypal.ts"] +S4["_shared/paypal-runtime.ts"] +S5["_shared/prompts.ts"] +F1 --> S1 +F1 --> S5 +F2 --> S1 +F3 --> S1 +F4 --> S1 +F4 --> S3 +F4 --> S4 +F5 --> S1 +F5 --> S3 +F5 --> S4 +F6 --> S1 +F6 --> S3 +F6 --> S4 +F7 --> S1 +``` + +**Diagram sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Performance Considerations +- Minimize payload sizes: compress large bodies where possible and avoid unnecessary fields. +- Cache frequently accessed data: use in-memory caches within function lifecycle for short-lived optimizations. +- Batch external calls: group API requests when feasible to reduce latency. +- Use streaming for large exports: handle binary streams efficiently to avoid memory spikes. +- Implement retry with exponential backoff for transient failures in external services. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid webhook signatures: verify secret keys and ensure headers are forwarded correctly. +- Malformed request bodies: validate JSON schema and provide descriptive error messages. +- Unauthorized access: confirm Authorization headers and token validity. +- External service timeouts: implement retries and circuit breakers; log detailed error contexts. +- Rate limit exceeded: adjust limits per user tier and communicate quotas to clients. + +Operational tips: +- Enable structured logging for all function invocations. +- Monitor error rates and latency percentiles. +- Use health checks to detect degraded states. + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Conclusion +The Supabase Edge Functions architecture cleanly separates handler logic from shared utilities, enabling consistent request/response handling, robust error management, and secure integrations with AI and payment providers. By adhering to standardized patterns for validation, authentication, and response formatting, the system remains maintainable and scalable. Follow the invocation examples and security guidelines to integrate clients effectively and mitigate risks. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Shared Utilities Library.md b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Shared Utilities Library.md new file mode 100644 index 0000000..913f034 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Backend Services/Shared Utilities Library.md @@ -0,0 +1,439 @@ +# Shared Utilities Library + + +**Referenced Files in This Document** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the shared utilities library used across all Edge Functions. It focuses on: +- Entitlement management for feature access control +- HTTP client wrapper with retry logic and error handling +- PayPal SDK integration with runtime configuration +- Prompt management system for AI interactions +- Common utility functions, configuration management, logging patterns, and testing utilities +- Usage examples showing how to import and use these shared modules in custom functions + +The goal is to provide a clear, practical guide for developers building or extending Edge Functions that rely on these shared capabilities. + +## Project Structure +The shared utilities live under supabase/functions/_shared and are consumed by individual Edge Function handlers. The key files are: +- entitlement.ts: Feature entitlement checks and caching +- http.ts: Typed HTTP client with retries and standardized errors +- paypal-runtime.ts: Runtime configuration loader for PayPal +- paypal.ts: PayPal SDK operations (orders, captures, webhooks) +- prompts.ts: Centralized prompt templates and helpers for AI calls + +```mermaid +graph TB +subgraph "Shared Utilities" +E["entitlement.ts"] +H["http.ts"] +PR["paypal-runtime.ts"] +P["paypal.ts"] +PT["prompts.ts"] +end +subgraph "Edge Functions" +AIP["ai-proxy/index.ts"] +CS["cancel-subscription/index.ts"] +CC["create-checkout/index.ts"] +CPO["create-paypal-order/index.ts"] +PW["paypal-webhook/index.ts"] +end +AIP --> PT +AIP --> H +CS --> E +CC --> E +CC --> H +CPO --> P +CPO --> PR +CPO --> H +PW --> P +PW --> H +PW --> E +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +## Core Components +- Entitlements: Provides feature gating based on user subscriptions and plan attributes. Includes caching strategies and consistent error responses. +- HTTP Client: A typed wrapper around fetch with exponential backoff, jitter, and categorized error types. +- PayPal Integration: Loads environment-specific runtime config and exposes order creation, capture, and webhook processing helpers. +- Prompts: Centralizes prompt templates and parameterization for AI interactions. + +Usage pattern in an Edge Function: +- Import only what you need from _shared +- Initialize any required runtime configuration once at module scope +- Use typed request/response objects to ensure consistency + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Architecture Overview +The shared utilities form a cohesive layer between Edge Function handlers and external systems (PayPal, AI providers). They standardize: +- Configuration loading +- Network behavior (retries, timeouts, error mapping) +- Access control (entitlements) +- Prompt templating for AI + +```mermaid +sequenceDiagram +participant Handler as "Edge Function Handler" +participant Ent as "Entitlements" +participant Http as "HTTP Client" +participant Pay as "PayPal Service" +participant Prov as "AI Provider" +Handler->>Ent : "Check feature access" +alt "Access denied" +Ent-->>Handler : "Error : insufficient entitlement" +else "Access granted" +Handler->>Http : "Make outbound call" +Http-->>Handler : "Response or Retryable Error" +alt "PayPal flow" +Handler->>Pay : "Create/Capture Order" +Pay-->>Handler : "Order result" +else "AI flow" +Handler->>Prov : "Send prompt" +Prov-->>Handler : "AI response" +end +end +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### Entitlement Management System +Purpose: +- Determine whether a user has access to a specific feature based on subscription state and plan attributes +- Provide consistent error semantics and optional caching to reduce repeated checks + +Key responsibilities: +- Resolve user identity and subscription context +- Evaluate entitlement rules per feature +- Cache results when appropriate +- Return structured success/failure responses + +Typical usage in an Edge Function: +- Import the entitlement checker +- Call it early in the handler to gate access +- Handle both allowed and denied paths + +```mermaid +flowchart TD +Start(["Function Entry"]) --> LoadCtx["Load user and subscription context"] +LoadCtx --> CheckRule["Evaluate entitlement rule for feature"] +CheckRule --> Allowed{"Allowed?"} +Allowed --> |Yes| Proceed["Proceed with function logic"] +Allowed --> |No| Deny["Return access denied error"] +Proceed --> End(["Function Exit"]) +Deny --> End +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### HTTP Client Wrapper with Retry Logic and Error Handling +Purpose: +- Standardize outbound HTTP calls across Edge Functions +- Implement robust retry policies with exponential backoff and jitter +- Normalize network and application errors into typed responses + +Key responsibilities: +- Build requests with headers, body, and timeout settings +- Apply retry policy for transient failures +- Map server and transport errors to consistent types +- Expose typed request/response interfaces + +Typical usage in an Edge Function: +- Import the HTTP client +- Configure base URL and default options +- Perform GET/POST/PUT/DELETE with typed payloads +- Handle retryable vs non-retryable errors explicitly + +```mermaid +flowchart TD +Start(["Request Initiated"]) --> Build["Build Request"] +Build --> Send["Send via fetch"] +Send --> Ok{"Status OK?"} +Ok --> |Yes| Parse["Parse Response"] +Ok --> |No| Classify["Classify Error"] +Classify --> Retryable{"Retryable?"} +Retryable --> |Yes| Backoff["Exponential Backoff + Jitter"] +Backoff --> Send +Retryable --> |No| ThrowErr["Throw Typed Error"] +Parse --> Done(["Return Result"]) +ThrowErr --> Done +``` + +**Diagram sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal SDK Integration with Runtime Configuration +Purpose: +- Load PayPal credentials and endpoints from runtime configuration +- Provide helpers for creating orders, capturing payments, and processing webhooks +- Keep sensitive configuration out of source code + +Key responsibilities: +- Read environment variables safely at runtime +- Initialize PayPal client with correct mode (sandbox/live) +- Encapsulate common PayPal flows with typed inputs/outputs +- Surface detailed error information for debugging + +Typical usage in an Edge Function: +- Import runtime config and PayPal service +- Create or capture orders using provided helpers +- Validate and process webhook events securely + +```mermaid +sequenceDiagram +participant Handler as "Edge Function" +participant RT as "Runtime Config" +participant PS as "PayPal Service" +participant API as "PayPal API" +Handler->>RT : "Load PayPal config" +RT-->>Handler : "Config object" +Handler->>PS : "Create order" +PS->>API : "POST /v2/checkout/orders" +API-->>PS : "Order ID" +PS-->>Handler : "Order result" +Handler->>PS : "Capture order" +PS->>API : "POST /v2/checkout/orders/{id}/capture" +API-->>PS : "Capture result" +PS-->>Handler : "Capture result" +``` + +**Diagram sources** +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +### Prompt Management System for AI Interactions +Purpose: +- Centralize prompt templates and parameters for AI calls +- Ensure consistent tone, structure, and safety constraints +- Simplify composition of complex prompts from reusable parts + +Key responsibilities: +- Define prompt templates and sections +- Compose final prompts with dynamic values +- Provide helpers for validation and formatting +- Integrate with the HTTP client to call AI providers + +Typical usage in an Edge Function: +- Import prompt builders +- Compose a prompt with user context +- Send to AI provider via HTTP client +- Parse and return structured results + +```mermaid +flowchart TD +Start(["Compose Prompt"]) --> LoadTemplate["Load template(s)"] +LoadTemplate --> FillVars["Fill dynamic variables"] +FillVars --> Validate["Validate prompt length/format"] +Validate --> Send["Send to AI provider"] +Send --> Parse["Parse AI response"] +Parse --> End(["Return result"]) +``` + +**Diagram sources** +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Example Edge Function Integrations +Below are representative integrations demonstrating how Edge Functions consume the shared utilities. These are illustrative patterns; adapt names and shapes to your implementation. + +- ai-proxy/index.ts + - Imports prompts and HTTP client + - Builds a prompt using the prompt manager + - Calls AI provider via HTTP client + - Returns structured AI response + +- create-paypal-order/index.ts + - Loads PayPal runtime config + - Creates an order via PayPal service + - Returns order details to caller + +- paypal-webhook/index.ts + - Validates webhook signature + - Processes event using PayPal service + - Updates entitlements if necessary + +- cancel-subscription/index.ts + - Checks entitlement before proceeding + - Performs cancellation flow + - Returns confirmation + +- create-checkout/index.ts + - Verifies entitlement + - Uses HTTP client to initiate checkout + - Returns checkout session or error + +**Section sources** +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) + +## Dependency Analysis +The shared utilities have minimal coupling and are designed for reuse across multiple Edge Functions. + +```mermaid +graph LR +H["http.ts"] --> |"used by"| P["paypal.ts"] +H --> |"used by"| AIP["ai-proxy/index.ts"] +H --> |"used by"| CC["create-checkout/index.ts"] +H --> |"used by"| PW["paypal-webhook/index.ts"] +PR["paypal-runtime.ts"] --> |"config for"| P +P --> |"uses"| H +E["entitlement.ts"] --> |"gates access"| CS["cancel-subscription/index.ts"] +E --> |"gates access"| CC +E --> |"updated by"| PW +PT["prompts.ts"] --> |"templates for"| AIP +``` + +**Diagram sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +## Performance Considerations +- Entitlement caching: Avoid redundant checks by caching recent results where safe. +- HTTP retries: Tune backoff and jitter to balance resilience and latency. +- Prompt size: Keep prompts concise to reduce token usage and improve response times. +- PayPal calls: Minimize round-trips by batching operations when possible. +- Cold starts: Initialize heavy dependencies lazily if they are not always used. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Insufficient entitlement: Verify user subscription state and entitlement rules. Check logs for denied paths. +- HTTP retry storms: Reduce retry counts or increase backoff caps; inspect upstream availability. +- PayPal config errors: Ensure runtime environment variables are set correctly for sandbox/live modes. +- Webhook verification failures: Confirm secret keys and payload signatures match expected formats. +- AI provider timeouts: Adjust timeouts and consider prompt simplification. + +Operational tips: +- Log contextual identifiers (user IDs, order IDs) consistently. +- Wrap third-party calls with explicit error categorization. +- Add health checks for critical dependencies. + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Conclusion +The shared utilities library standardizes cross-cutting concerns across Edge Functions: +- Entitlements enforce feature access consistently +- The HTTP client ensures resilient networking +- PayPal integration abstracts payment flows and configuration +- Prompt management centralizes AI interaction patterns + +Adopting these modules improves reliability, maintainability, and developer productivity. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Quick Start: Using Shared Modules in Your Edge Function +- Import the modules you need from _shared +- Initialize runtime configuration once at module scope +- Gate access with entitlements before performing sensitive operations +- Use the HTTP client for outbound calls with typed requests/responses +- Compose prompts using the prompt manager for AI features +- Handle errors using the standardized error types + +Example references: +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) + +**Section sources** +- [index.ts (ai-proxy)](file://supabase/functions/ai-proxy/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Data Flow Architecture.md b/.qoder/repowiki/en/content/Architecture Overview/Data Flow Architecture.md new file mode 100644 index 0000000..f6234b4 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Data Flow Architecture.md @@ -0,0 +1,344 @@ +# Data Flow Architecture + + +**Referenced Files in This Document** +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/store.jsx](file://src/store.jsx) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document describes the end-to-end data flow architecture, covering the complete lifecycle from user input to local persistence and cloud synchronization. It explains real-time sync mechanisms, conflict resolution strategies, offline support, event-driven patterns, state synchronization protocols, and consistency guarantees. It also includes sequence diagrams for transformation pipelines, caching strategies, performance optimizations, validation, error recovery, and backup procedures. + +## Project Structure +The application is a web-first app with optional mobile packaging. The data layer is implemented as modular libraries: +- Local storage abstraction +- Sync engine coordinating local state and remote changes +- Cloud client for Supabase and serverless functions +- Service Worker for offline caching and background tasks +- Frontend store wiring UI to the data layer + +```mermaid +graph TB +subgraph "Browser" +UI["UI Components"] +Store["Frontend Store"] +Storage["Local Storage Abstraction"] +Sync["Sync Engine"] +SW["Service Worker"] +end +subgraph "Cloud" +Supabase["Supabase Client"] +SF["Serverless Functions"] +DB[(Database)] +end +UI --> Store +Store --> Sync +Store --> Storage +Sync --> Supabase +Sync --> SF +SW --> Storage +SW --> Supabase +Supabase --> DB +SF --> DB +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Core Components +- Local Storage Abstraction: Provides a consistent interface for reading/writing entities locally, including versioning and change tracking. +- Sync Engine: Orchestrates bidirectional synchronization between local state and remote data, handling batching, retries, and conflict resolution. +- Cloud Client: Encapsulates Supabase client usage and calls to serverless functions for specialized operations (e.g., billing, AI proxy). +- Frontend Store: Centralized state container that exposes reactive APIs to components and coordinates sync triggers. +- Service Worker: Caches assets and API responses, intercepts network requests, and performs background sync when online. +- Serverless Functions: Stateless endpoints for sensitive or heavy operations, using shared HTTP utilities. + +Key responsibilities: +- Validation at ingestion points (UI and storage) +- Event-driven updates via store subscriptions +- Conflict detection and resolution policies +- Offline-first behavior with queued mutations +- Real-time subscriptions for live updates + +**Section sources** +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/store.jsx](file://src/store.jsx) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Architecture Overview +The system follows an offline-first, event-driven architecture with a clear separation between UI, state, persistence, and sync layers. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "UI Components" +participant Store as "Frontend Store" +participant Storage as "Local Storage" +participant Sync as "Sync Engine" +participant Cloud as "Supabase/Functions" +participant DB as "Database" +User->>UI : "Create/Update entity" +UI->>Store : "Dispatch action" +Store->>Storage : "Write locally" +Store-->>UI : "Emit update event" +Store->>Sync : "Queue mutation" +Sync->>Cloud : "Apply mutation remotely" +Cloud->>DB : "Persist change" +DB-->>Cloud : "Ack" +Cloud-->>Sync : "Remote result" +Sync->>Storage : "Merge and reconcile" +Sync-->>Store : "Emit sync events" +Store-->>UI : "Render latest state" +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Local Storage Abstraction +Responsibilities: +- Provide typed CRUD operations over local storage +- Maintain entity versions and timestamps for conflict detection +- Expose change listeners for downstream consumers +- Support batched writes and atomic transactions where possible + +Data model highlights: +- Entities include unique identifiers, version counters, and last-modified timestamps +- Indexes are maintained for common queries to optimize reads + +Validation: +- Input validation before persisting to ensure schema compliance +- Sanitization of user inputs to prevent corruption + +Error handling: +- Graceful fallbacks on quota exceeded or storage unavailable +- Retry logic with exponential backoff for transient failures + +Backup: +- Periodic export of critical entities to downloadable archives +- Incremental snapshots for faster restore + +**Section sources** +- [src/lib/storage.js](file://src/lib/storage.js) + +### Sync Engine +Responsibilities: +- Queue local mutations and apply them to the cloud +- Subscribe to remote changes and merge into local state +- Detect conflicts and apply resolution policies +- Manage connectivity state and retry scheduling + +Real-time sync: +- Subscribes to relevant tables/channels for live updates +- Applies incremental patches to minimize re-renders + +Conflict resolution: +- Last-write-wins with version checks +- Field-level merging for non-conflicting fields +- Fallback to manual resolution prompts when necessary + +Offline support: +- Mutations are persisted locally until connectivity resumes +- Background sync attempts when connection is restored + +Consistency guarantees: +- At-least-once delivery for mutations +- Idempotent operations keyed by operation IDs +- Eventual consistency across devices after reconciliation + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) + +### Cloud Client +Responsibilities: +- Wrap Supabase client initialization and configuration +- Provide typed methods for database operations +- Call serverless functions for sensitive or complex workflows + +Integration points: +- Authentication context propagation +- Error normalization and retry policies +- Rate limiting and request deduplication + +Security: +- Enforces RLS policies defined in migrations +- Uses short-lived tokens and secure headers + +**Section sources** +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Frontend Store +Responsibilities: +- Centralize application state and expose reactive APIs +- Dispatch actions and manage side effects +- Coordinate sync triggers and UI updates + +Event-driven patterns: +- Publish/subscribe model for decoupled components +- Throttled debounced updates for performance + +State synchronization protocol: +- Actions produce optimistic updates +- Sync results reconcile state and roll back on failure + +**Section sources** +- [src/store.jsx](file://src/store.jsx) + +### Service Worker +Responsibilities: +- Cache static assets and API responses +- Intercept network requests to serve cached content offline +- Perform background sync for pending mutations + +Caching strategy: +- Stale-while-revalidate for list endpoints +- Cache-busting for immutable assets +- Priority queues for high-value resources + +Background sync: +- Schedules retries for failed mutations +- Batches small mutations to reduce overhead + +**Section sources** +- [public/sw.js](file://public/sw.js) + +### Serverless Functions +Responsibilities: +- Host business logic requiring server-side access +- Integrate third-party services securely +- Provide standardized HTTP interfaces + +Shared utilities: +- Common HTTP helpers for request/response handling +- Shared entitlement checks and prompt templates + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Dependency Analysis +The following diagram shows key dependencies among core modules. + +```mermaid +graph LR +UI["UI Components"] --> Store["Frontend Store"] +Store --> Storage["Local Storage Abstraction"] +Store --> Sync["Sync Engine"] +Sync --> Cloud["Cloud Client"] +Cloud --> Supabase["Supabase Client"] +Cloud --> SF["Serverless Functions"] +SW["Service Worker"] --> Storage +SW --> Supabase +Supabase --> DB["Database"] +SF --> DB +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Performance Considerations +- Optimistic UI updates to reduce perceived latency +- Debounce/throttle frequent mutations to avoid excessive sync traffic +- Batched writes and merges to minimize storage I/O +- Selective subscriptions to limit real-time payload size +- Efficient caching in the service worker to reduce network round-trips +- Idempotent operations to prevent duplicate work during retries + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Network errors during sync: + - Verify connectivity and retry schedule + - Check rate limits and backoff settings +- Conflicts not resolving: + - Inspect version fields and timestamps + - Validate conflict resolution policy for affected entities +- Storage quota exceeded: + - Trigger cleanup routines and archive old data + - Prompt users to export and clear local cache +- Service Worker stale cache: + - Invalidate caches for affected endpoints + - Force refresh and re-validate resources +- Database permission errors: + - Review RLS policies and function permissions + - Ensure correct auth context propagation + +Operational checks: +- Confirm subscription channels are active +- Validate migration status and schema compatibility +- Monitor function logs for server-side errors + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Conclusion +The data flow architecture emphasizes offline-first reliability, event-driven responsiveness, and robust synchronization with conflict resolution. By separating concerns across storage, sync, cloud, and UI layers, the system achieves scalability and maintainability while ensuring data consistency and resilience under adverse conditions. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Build & Development Configuration.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Build & Development Configuration.md new file mode 100644 index 0000000..26f3eea --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Build & Development Configuration.md @@ -0,0 +1,308 @@ +# Build & Development Configuration + + +**Referenced Files in This Document** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [index.html](file://index.html) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [public/sw.js](file://public/sw.js) +- [src/main.jsx](file://src/main.jsx) +- [src/mobile.js](file://src/mobile.js) +- [.github/workflows/supabase.yml](file:///.github/workflows/supabase.yml) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the build system and development configuration for the project, focusing on Vite-based web builds, Capacitor mobile app setup, deployment configurations for Netlify and Vercel, environment variable management, build scripts, dependency management, and best practices for performance and debugging. It is intended for developers who need to set up local development, run tests, build for production, and deploy across platforms consistently. + +## Project Structure +The repository uses a modern frontend stack with Vite as the build tool, React components under src, and platform-specific integrations via Capacitor for mobile. Deployment targets include Netlify and Vercel, with CI defined for Supabase-related tasks. + +```mermaid +graph TB +A["package.json
Scripts & Dependencies"] --> B["vite.config.js
Build & Dev Server Config"] +B --> C["index.html
App Entry HTML"] +B --> D["public/*
Static Assets (manifest, sw)"] +B --> E["src/*
React App Source"] +E --> F["src/main.jsx
App Bootstrap"] +E --> G["src/mobile.js
Mobile Entrypoint"] +H["capacitor.config.ts
Capacitor App Config"] --> I["mobile/
Native Projects"] +J["netlify.toml
Netlify Deploy Config"] --> K["Netlify Hosting"] +L["vercel.json
Vercel Deploy Config"] --> M["Vercel Hosting"] +N[".github/workflows/supabase.yml
CI for Supabase"] --> O["Supabase Functions/Migrations"] +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [index.html](file://index.html) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [public/sw.js](file://public/sw.js) +- [src/main.jsx](file://src/main.jsx) +- [src/mobile.js](file://src/mobile.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file:///.github/workflows/supabase.yml) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [index.html](file://index.html) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file:///.github/workflows/supabase.yml) + +## Core Components +- Build tooling: Vite configuration controls dev server behavior, asset handling, and production optimizations. +- Mobile integration: Capacitor config defines the native app wrapper and bridging settings. +- Deployment: Netlify and Vercel configuration files define redirects, rewrites, and build commands. +- Environment variables: Managed through Vite’s env loading conventions and runtime access patterns. +- Scripts: npm scripts orchestrate development, building, testing, and mobile workflows. + +Key responsibilities: +- vite.config.js: Dev server options, plugins, asset optimization, output structure. +- capacitor.config.ts: App ID, name, webDir, and platform-specific options. +- netlify.toml and vercel.json: Routing rules, SPA fallbacks, build command overrides. +- package.json: Scripts, dependencies, and devDependencies. + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [package.json](file://package.json) + +## Architecture Overview +The application follows a standard Vite + React architecture with optional Capacitor mobile packaging. The build pipeline produces static assets served by hosting platforms. Environment variables are injected at build time or runtime depending on their naming convention. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Vite as "Vite Dev Server" +participant App as "React App (main.jsx)" +participant Capacitor as "Capacitor Bridge" +participant Host as "Host Platform (Netlify/Vercel)" +Dev->>Vite : Start dev server +Vite-->>Dev : Hot reload updates +Vite->>App : Bundle and serve source +App->>Capacitor : Initialize bridge (mobile only) +Dev->>Host : Deploy built assets +Host-->>Dev : Live site/app +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/mobile.js](file://src/mobile.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Detailed Component Analysis + +### Vite Configuration and Asset Optimization +Vite is configured to provide a fast development experience and optimized production builds. Typical areas covered include: +- Dev server options: port, open behavior, proxy settings if needed. +- Plugins: React support, path aliases, and any additional transformations. +- Build options: minification, code splitting, chunk sizing, sourcemaps. +- Asset handling: image, font, and media processing; public directory usage. +- Output structure: base path for deployments behind subpaths. + +Best practices: +- Use environment-specific configs when necessary. +- Enable sourcemaps for production debugging where appropriate. +- Configure asset sizes and split points to improve load times. + +**Section sources** +- [vite.config.js](file://vite.config.js) + +### Capacitor Mobile App Configuration +Capacitor wraps the web build into native apps. Key configuration aspects: +- App identity: identifier and display name. +- Web directory: points to the Vite build output. +- Platform options: iOS and Android specific settings. +- Plugin initialization: how the app integrates with native features. + +Development workflow: +- Build web assets first, then sync to native projects. +- Run on device or emulator using Capacitor CLI. +- Rebuild and resync after changes. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/mobile.js](file://src/mobile.js) + +### Deployment Configurations: Netlify and Vercel +Both platforms require SPA routing fallbacks and correct build commands. + +Netlify: +- Build command: typically runs the Vite build script. +- Publish directory: points to the Vite output folder. +- Redirects/rewrites: ensure client-side routes resolve correctly. + +Vercel: +- Build command: same as Netlify. +- Output directory: same as Netlify. +- Rewrites: configure SPA fallbacks for client routes. + +Environment variables: +- Define required variables in each platform’s dashboard. +- Ensure Vite-compatible prefixes if used. + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +### Environment Variable Management +Vite supports environment variables loaded from .env files. Common patterns: +- .env.local for local overrides. +- .env.development and .env.production for environment-specific values. +- Prefixing variables based on Vite’s exposure rules. + +Runtime access: +- Access variables via the Vite-provided global object in the browser. +- Avoid exposing secrets; use server-side functions for sensitive operations. + +CI considerations: +- Store secrets in platform secret managers. +- Inject variables during build steps. + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +### Build Scripts and Dependency Management +npm scripts in package.json orchestrate common tasks: +- Development: start dev server with hot reloading. +- Build: generate production assets. +- Test: run unit/integration tests. +- Mobile: build web assets and sync to native projects. + +Dependency management: +- Use package-lock.json to lock versions. +- Keep dependencies updated regularly. +- Separate devDependencies from runtime dependencies. + +**Section sources** +- [package.json](file://package.json) + +### Service Worker and PWA Assets +The public directory includes a service worker and manifest for PWA capabilities: +- manifest.webmanifest: app metadata for installability. +- sw.js: caching strategies and offline behavior. + +Integration: +- Register the service worker from the app entrypoint. +- Ensure cache keys align with build outputs. + +**Section sources** +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [public/sw.js](file://public/sw.js) +- [src/main.jsx](file://src/main.jsx) + +### CI Workflow for Supabase +A GitHub Actions workflow automates Supabase-related tasks such as migrations or function deployments. It ensures consistent backend state across environments. + +**Section sources** +- [.github/workflows/supabase.yml](file:///.github/workflows/supabase.yml) + +## Dependency Analysis +The following diagram shows how core configuration files relate to each other and to the build/deploy process. + +```mermaid +graph LR +P["package.json"] --> V["vite.config.js"] +V --> I["index.html"] +V --> S["src/main.jsx"] +V --> M["public/manifest.webmanifest"] +V --> W["public/sw.js"] +C["capacitor.config.ts"] --> N["native projects (mobile/)"] +N1["netlify.toml"] --> H1["Netlify"] +N2["vercel.json"] --> H2["Vercel"] +CI[".github/workflows/supabase.yml"] --> SB["Supabase"] +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file:///.github/workflows/supabase.yml) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file:///.github/workflows/supabase.yml) + +## Performance Considerations +- Code splitting: leverage dynamic imports to reduce initial bundle size. +- Asset optimization: compress images and fonts; consider next-gen formats. +- Caching strategy: configure long-term caching for immutable assets and short-term for frequently changing files. +- Tree-shaking: remove unused code by importing modules explicitly. +- Minification and dead code elimination: enabled in production builds. +- Prefetching and preloading: prioritize critical resources. +- Service worker caching: implement efficient cache-first strategies for static assets. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Dev server not starting: check port conflicts and environment variables. +- Missing environment variables: verify .env files and platform dashboards. +- SPA routing errors: confirm redirects/rewrites in Netlify/Vercel configs. +- Mobile build failures: ensure webDir points to the correct build output. +- Service worker not updating: clear caches and adjust cache-busting keys. +- Large bundles: analyze chunks and optimize imports. + +Debugging techniques: +- Enable sourcemaps in development and optionally in production. +- Use browser dev tools to inspect network requests and cache headers. +- Log environment variables safely without exposing secrets. +- Use platform preview URLs to validate deployment behavior. + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Conclusion +This project uses Vite for fast development and optimized builds, Capacitor for mobile packaging, and standardized deployment configurations for Netlify and Vercel. By following the documented scripts, environment variable practices, and performance recommendations, teams can maintain a smooth development workflow and reliable deployments across web and mobile platforms. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Quick Start Checklist +- Install dependencies using the package manager. +- Start the development server and verify hot reloading. +- Build for production and review output size. +- Sync to mobile projects and test on device/emulator. +- Deploy to Netlify or Vercel with correct environment variables. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Component System.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Component System.md new file mode 100644 index 0000000..40fb0fb --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Component System.md @@ -0,0 +1,431 @@ +# Component System + + +**Referenced Files in This Document** +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document describes the React component system with a focus on the reusable architecture and integration patterns used across the application. It explains how core components compose together, how props are passed and validated, how state is managed at both local and global levels, and how lifecycle methods and effects coordinate data flow. The goal is to help developers understand the structure, reuse patterns, and customization options for Layout, ScanForm, ResultView, Toast, and Settings. + +## Project Structure +The React application is bootstrapped by an entry point that renders the root component tree. The main application shell uses a layout wrapper to provide consistent chrome (header, navigation, content area). Feature pages and utilities are organized under src/components and src/hooks respectively. Global state and shared services live in src/lib and src/store. + +```mermaid +graph TB +A["main.jsx"] --> B["App.jsx"] +B --> C["Layout.jsx"] +C --> D["ScanForm.jsx"] +C --> E["ResultView.jsx"] +C --> F["Settings.jsx"] +C --> G["Toast.jsx"] +C --> H["AccountPage.jsx"] +C --> I["AiAssistant.jsx"] +C --> J["Tracker.jsx"] +K["store.jsx"] -.-> B +L["useCountUp.js"] -.-> D +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) + +## Core Components +This section summarizes each key component’s purpose, typical props, internal state, and interactions. + +- Layout + - Purpose: Provides consistent page chrome, navigation, and content slotting. + - Props: children, optional theme or mode flags, navigation callbacks. + - State: Local UI toggles (e.g., drawer open/close), active route context. + - Lifecycle: Mounts once; may initialize analytics or global listeners. + - Composition: Wraps feature pages and shared UI like Toast. + +- ScanForm + - Purpose: Collects user input for scanning or analysis tasks. + - Props: onSubmit callback, initial values, validation rules, loading flag. + - State: Form fields, errors, submission status. + - Lifecycle: Effects to sync with external stores or URL params; cleanup on unmount. + - Events: Field changes, validation triggers, submit handler. + +- ResultView + - Purpose: Displays analysis results and actions (export, share). + - Props: result object, visibility flags, action handlers. + - State: Temporary UI state (e.g., expanded sections). + - Lifecycle: Effects to compute derived views or persist last result. + - Events: Action clicks (copy, export, share). + +- Toast + - Purpose: Global notification surface. + - Props: message, type, duration, onClose. + - State: Internal queue and timers. + - Lifecycle: Auto-dismiss after duration; cleanup timers on unmount. + - Events: Dismiss, auto-close. + +- Settings + - Purpose: User preferences and configuration panel. + - Props: settings object, onChange handler, save callback. + - State: Draft settings, validation feedback. + - Lifecycle: Effects to load persisted settings; debounce saves. + - Events: Save, reset, field changes. + +Additional components: +- AccountPage: User account management and profile editing. +- AiAssistant: AI-powered assistant interface and chat-like interactions. +- Tracker: Tracking and metrics display. + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Architecture Overview +The application follows a composition-first pattern: App orchestrates routing and global state, Layout provides the shell, and feature components render within it. Shared notifications via Toast are mounted at the top level. Global store (if present) is consumed where needed. + +```mermaid +sequenceDiagram +participant Entry as "main.jsx" +participant Root as "App.jsx" +participant Shell as "Layout.jsx" +participant Form as "ScanForm.jsx" +participant View as "ResultView.jsx" +participant Store as "store.jsx" +Entry->>Root : Render root +Root->>Shell : Provide layout + routes +Shell->>Form : Render form when active +Form->>Store : Read/write shared state (optional) +Form-->>Shell : Emit submit event +Shell->>View : Show results based on form output +View-->>Shell : Trigger actions (export/share) +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) + +## Detailed Component Analysis + +### Layout +- Responsibilities: + - Provide header, sidebar/drawer, and content area. + - Manage active navigation state and responsive behavior. + - Compose global Toast container if applicable. +- Props Interface: + - children: Node | ReactNode + - theme?: string + - onNavigate?: (route) => void + - className?: string +- State Management: + - Local UI toggles (drawer, mobile menu). + - Optional integration with global store for theme or user context. +- Lifecycle Methods: + - useEffect to attach global keyboard shortcuts or resize listeners. + - Cleanup functions to remove listeners. +- Event Handling: + - Navigation clicks update active route. + - Drawer toggle updates local state. +- Composition Patterns: + - Slot-based rendering via children prop. + - Higher-order wrappers for authenticated-only sections. + +```mermaid +classDiagram +class Layout { ++props.children ++props.theme ++props.onNavigate ++state.drawerOpen ++toggleDrawer() ++handleNavigate(route) +} +class Toast { ++props.message ++props.type ++props.duration ++props.onClose +} +Layout --> Toast : "renders globally" +``` + +**Diagram sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) + +### ScanForm +- Responsibilities: + - Capture inputs for scanning or analysis. + - Validate fields and manage submission lifecycle. +- Props Interface: + - initialValues?: Record + - onSubmit(values): Promise + - validate?(values): Record + - loading?: boolean + - disabled?: boolean +- State Management: + - Local form state (fields, errors, touched). + - Submission status and error messages. +- Lifecycle Methods: + - useEffect to sync with URL query parameters or global store. + - Cleanup to abort pending requests or clear timeouts. +- Event Handling: + - onChange per field updates local state and re-validates. + - onBlur marks fields as touched. + - onSubmit calls provided callback with sanitized values. +- Validation: + - Inline validation function or library-driven rules. + - Real-time feedback and error summaries. + +```mermaid +flowchart TD +Start(["Mount"]) --> Init["Initialize fields from props or defaults"] +Init --> Change["Field change handler"] +Change --> Validate["Run validation rules"] +Validate --> Errors{"Errors found?"} +Errors --> |Yes| ShowErr["Display inline errors"] +Errors --> |No| ClearErr["Clear field errors"] +ShowErr --> Submit["Submit button clicked"] +ClearErr --> Submit +Submit --> CallAPI["Call onSubmit(values)"] +CallAPI --> Success{"Success?"} +Success --> |Yes| Reset["Reset form or show success"] +Success --> |No| HandleError["Show global error toast"] +Reset --> End(["Unmount"]) +HandleError --> End +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +### ResultView +- Responsibilities: + - Present analysis results with interactive actions. + - Support expand/collapse sections and copy/export flows. +- Props Interface: + - result: object + - visible?: boolean + - onExport?: () => void + - onShare?: () => void + - onCopy?: () => void +- State Management: + - Local UI toggles for sections. + - Derived computed views from result. +- Lifecycle Methods: + - useEffect to persist last result or trigger side effects on result change. +- Event Handling: + - Action buttons call provided handlers. + - Keyboard accessibility for actions. + +```mermaid +sequenceDiagram +participant Parent as "Parent" +participant RV as "ResultView" +Parent->>RV : Pass result and actions +RV->>RV : Compute derived view +RV-->>Parent : onExport() / onShare() / onCopy() +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### Toast +- Responsibilities: + - Display transient notifications. + - Manage queue and auto-dismiss timers. +- Props Interface: + - message: string + - type?: "info" | "success" | "warning" | "error" + - duration?: number + - onClose?: () => void +- State Management: + - Internal queue of toasts. + - Active timer IDs for auto-dismiss. +- Lifecycle Methods: + - useEffect to schedule dismiss. + - Cleanup to clear timers on unmount. +- Event Handling: + - Close button triggers onClose. + - Click-to-dismiss behavior. + +```mermaid +classDiagram +class Toast { ++props.message ++props.type ++props.duration ++props.onClose ++state.queue ++add(message,type,duration) ++remove(id) +} +``` + +**Diagram sources** +- [Toast.jsx](file://src/components/Toast.jsx) + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) + +### Settings +- Responsibilities: + - Allow users to adjust app preferences. + - Persist settings locally or remotely. +- Props Interface: + - settings: object + - onChange(settings): void + - onSave?: (settings) => Promise + - resetToDefaults?: () => void +- State Management: + - Draft settings state separate from saved settings. + - Validation and conflict resolution. +- Lifecycle Methods: + - useEffect to load persisted settings on mount. + - Debounced save effect to avoid excessive writes. +- Event Handling: + - Field changes update draft state. + - Save triggers persistence and notifies parent. + +```mermaid +flowchart TD +Load(["Mount"]) --> Fetch["Load persisted settings"] +Fetch --> Draft["Create draft copy"] +Draft --> Edit["User edits fields"] +Edit --> Validate["Validate draft"] +Validate --> SaveBtn["Save clicked"] +SaveBtn --> Persist["Persist settings"] +Persist --> Notify["Notify parent via onChange/onSave"] +Notify --> Done(["Done"]) +``` + +**Diagram sources** +- [Settings.jsx](file://src/components/Settings.jsx) + +**Section sources** +- [Settings.jsx](file://src/components/Settings.jsx) + +### Additional Components +- AccountPage + - Manages user account details and authentication-related UI. + - Integrates with auth flows and global store. +- AiAssistant + - Provides AI assistant interactions and streaming responses. + - Uses hooks for debouncing and real-time updates. +- Tracker + - Displays tracking metrics and charts. + - Consumes data from lib modules and global store. + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Dependency Analysis +Components depend on: +- Global store for shared state (user, settings, results). +- Hooks for reusable logic (e.g., useCountUp). +- Utility libraries for formatting, validation, and storage. + +```mermaid +graph LR +Store["store.jsx"] --> App["App.jsx"] +Store --> Layout["Layout.jsx"] +Store --> ScanForm["ScanForm.jsx"] +Store --> ResultView["ResultView.jsx"] +Hook["useCountUp.js"] --> ScanForm +Hook --> ResultView +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Performance Considerations +- Memoization: Use memoized selectors and derived computations in ResultView to avoid unnecessary re-renders. +- Debounce: Debounce heavy operations in Settings and ScanForm to reduce frequent writes and validations. +- Lazy Loading: Consider lazy-loading non-critical components (e.g., AiAssistant) to improve initial load time. +- List Rendering: Optimize lists in Tracker with stable keys and virtualization if datasets grow large. +- Effect Cleanup: Ensure all timers, listeners, and subscriptions are cleaned up to prevent memory leaks. + +## Troubleshooting Guide +Common issues and resolutions: +- Form not submitting: + - Verify onSubmit prop is provided and returns a promise. + - Check validation rules for blocking conditions. +- Toast not appearing: + - Ensure Toast container is rendered at the root. + - Confirm duration and onClose handlers are set correctly. +- Settings not persisting: + - Inspect onSave implementation and error handling. + - Validate that draft vs saved settings are properly synchronized. +- ResultView stale data: + - Confirm result prop updates and dependencies in effects. + - Avoid mutating result objects directly; pass new references. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Conclusion +The component system emphasizes composition, clear prop interfaces, and predictable state management. Layout centralizes chrome and navigation, while feature components encapsulate domain-specific logic. Toast provides a consistent notification experience, and Settings ensures user preferences are manageable and persistent. By following these patterns, developers can extend functionality, customize behaviors, and maintain a scalable architecture. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Display Components.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Display Components.md new file mode 100644 index 0000000..81428e3 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Display Components.md @@ -0,0 +1,333 @@ +# Display Components + + +**Referenced Files in This Document** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [tone.js](file://src/lib/tone.js) +- [index.css](file://src/index.css) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document focuses on display and presentation components with an emphasis on the ResultView component. It explains how results are rendered, how data states are handled (loading, success, error), and how dynamic content is presented to users. It also documents prop interfaces for data binding, formatting options, and interactive features, along with visualization patterns used across the result rendering pipeline. + +## Project Structure +The display layer is primarily implemented as React components under src/components. The ResultView component consumes analysis outputs produced by library modules under src/lib and renders them using shared styles from src/index.css. State management and application wiring are provided by src/store.jsx and src/App.jsx. + +```mermaid +graph TB +subgraph "Presentation Layer" +RV["ResultView.jsx"] +APP["App.jsx"] +end +subgraph "State Management" +STORE["store.jsx"] +end +subgraph "Analysis Libraries" +ANALYZE["analyze.js"] +SCORING["scoring.js"] +STATS["stats.js"] +REDFLAGS["redflags.js"] +FOLLOWUPS["followups.js"] +NEXTACTION["nextaction.js"] +TONE["tone.js"] +end +subgraph "Styling" +CSS["index.css"] +end +APP --> RV +RV --> STORE +RV --> ANALYZE +RV --> SCORING +RV --> STATS +RV --> REDFLAGS +RV --> FOLLOWUPS +RV --> NEXTACTION +RV --> TONE +RV --> CSS +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [tone.js](file://src/lib/tone.js) +- [index.css](file://src/index.css) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +## Core Components +- ResultView: Renders analysis outcomes including scores, statistics, red flags, follow-ups, next actions, and tone insights. It manages user interactions such as toggling details, copying text, and navigating between sections. It adapts its UI based on data state (loading, ready, error). +- App: Wires up global state and provides context or props to child components, including ResultView. +- store: Centralized state container that holds analysis inputs, results, and UI flags consumed by ResultView. + +Key responsibilities: +- Data binding: Consumes structured analysis results and maps them to UI sections. +- Formatting: Applies number formatting, thresholds, and labels via library helpers. +- Interactivity: Supports expand/collapse, copy-to-clipboard, and navigation anchors. +- State handling: Displays loading indicators, empty states, and error messages. + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview +The ResultView component orchestrates multiple analysis libraries to produce a cohesive presentation. Inputs flow from the store into ResultView, which then calls library functions to compute derived views and render them. Styling is applied through shared CSS classes. + +```mermaid +sequenceDiagram +participant User as "User" +participant App as "App.jsx" +participant Store as "store.jsx" +participant RV as "ResultView.jsx" +participant Analyze as "analyze.js" +participant Scoring as "scoring.js" +participant Stats as "stats.js" +participant RedFlags as "redflags.js" +participant Followups as "followups.js" +participant NextAction as "nextaction.js" +participant Tone as "tone.js" +User->>App : Trigger analysis +App->>Store : Update input state +Store-->>RV : Provide results/state +RV->>Analyze : Compute analysis output +RV->>Scoring : Derive score(s) +RV->>Stats : Compute summary stats +RV->>RedFlags : Identify red flags +RV->>Followups : Generate follow-up items +RV->>NextAction : Determine next action +RV->>Tone : Infer tone insights +RV-->>User : Render result sections +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [tone.js](file://src/lib/tone.js) + +## Detailed Component Analysis + +### ResultView Component +ResultView is the primary display surface for analysis outcomes. It composes multiple sub-sections, each responsible for a specific aspect of the result set. + +#### Rendering Strategy +- Sectioned layout: Scores, statistics, red flags, follow-ups, next actions, and tone insights are grouped into distinct panels. +- Conditional rendering: Sections appear only when relevant data exists; otherwise, placeholders or empty-state messages are shown. +- Progressive disclosure: Expandable panels allow users to reveal detailed information without cluttering the initial view. +- Accessibility: Semantic headings, ARIA attributes, and keyboard navigation support improve usability. + +#### Data States Handling +- Loading: Shows a spinner or skeleton placeholders while analysis runs. +- Ready: Displays computed results with formatted values and actionable items. +- Error: Presents a friendly message with retry guidance and logs diagnostic info. + +#### Prop Interfaces +Props enable flexible data binding and customization: +- data: Structured analysis result object containing scores, stats, flags, follow-ups, next actions, and tone insights. +- formatOptions: Configuration for number formatting, date/time localization, threshold overrides, and label customizations. +- uiConfig: Flags controlling visibility of sections, default expanded states, and theme hints. +- callbacks: Handlers for user interactions such as copy-to-clipboard, export, share, and navigation. +- accessibility: Options for screen reader announcements and focus management. + +Example prop usage patterns: +- Binding scores and thresholds via data.scores and formatOptions.thresholds. +- Customizing section titles and descriptions via uiConfig.labels. +- Enabling or disabling interactive features via uiConfig.features. + +#### Interactive Features +- Copy-to-clipboard: One-click copying of key metrics or summaries. +- Export/share: Generating downloadable reports or shareable links. +- Navigation anchors: Jumping to specific sections within the result page. +- Expand/collapse: Revealing detailed breakdowns for scores and flags. + +#### Visualization Patterns +- Score cards: Compact displays of numeric scores with contextual labels and trend indicators. +- Progress bars: Visual representation of metric levels relative to thresholds. +- Lists and badges: Red flags and follow-ups presented as actionable items with severity indicators. +- Summary tiles: Key statistics aggregated at a glance. + +```mermaid +classDiagram +class ResultView { ++props.data ++props.formatOptions ++props.uiConfig ++props.callbacks ++props.accessibility ++render() +-formatNumber(value, options) +-copyToClipboard(text) +-toggleSection(id) +-handleExport() +} +class ScoreCard { ++value ++label ++threshold ++trend ++render() +} +class StatTile { ++metric ++value ++unit ++render() +} +class FlagList { ++flags ++severityMap ++render() +} +class FollowUpList { ++items ++actions ++render() +} +class NextActionPanel { ++action ++reasoning ++render() +} +class ToneInsights { ++tone ++summary ++render() +} +ResultView --> ScoreCard : "renders" +ResultView --> StatTile : "renders" +ResultView --> FlagList : "renders" +ResultView --> FollowUpList : "renders" +ResultView --> NextActionPanel : "renders" +ResultView --> ToneInsights : "renders" +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### Library Integration Points +ResultView delegates computation to specialized libraries: +- analyze.js: Produces core analysis outputs from input data. +- scoring.js: Computes normalized scores and applies thresholds. +- stats.js: Aggregates descriptive statistics and summaries. +- redflags.js: Identifies critical issues and categorizes severity. +- followups.js: Generates recommended follow-up tasks. +- nextaction.js: Determines prioritized next steps. +- tone.js: Infers sentiment or tone characteristics. + +These modules return structured objects consumed by ResultView’s rendering logic. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [tone.js](file://src/lib/tone.js) + +### Styling and Theming +Shared styles are defined in index.css and referenced by ResultView and related components. Classes encapsulate layout, typography, color tokens, and responsive behavior. Theme-aware variants can be applied via CSS variables or modifier classes. + +**Section sources** +- [index.css](file://src/index.css) + +## Dependency Analysis +ResultView depends on multiple analysis libraries and shared styling. The following diagram shows direct dependencies and their roles in the rendering pipeline. + +```mermaid +graph LR +RV["ResultView.jsx"] --> ANA["analyze.js"] +RV --> SCR["scoring.js"] +RV --> STA["stats.js"] +RV --> RF["redflags.js"] +RV --> FU["followups.js"] +RV --> NA["nextaction.js"] +RV --> TO["tone.js"] +RV --> CSS["index.css"] +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [tone.js](file://src/lib/tone.js) +- [index.css](file://src/index.css) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [tone.js](file://src/lib/tone.js) +- [index.css](file://src/index.css) + +## Performance Considerations +- Memoization: Cache expensive computations and derived views to avoid re-renders when inputs have not changed. +- Lazy rendering: Defer heavy sections until they become visible or interacted with. +- Batch updates: Consolidate state changes to minimize reflows and repaints. +- Efficient list rendering: Use stable keys and virtualization for long lists of flags or follow-ups. +- Minimal DOM mutations: Prefer declarative updates and avoid unnecessary inline styles. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing data fields: Ensure all required properties exist in the data prop before rendering; provide fallbacks for optional fields. +- Incorrect formatting: Validate formatOptions and normalize units before passing to formatters. +- Interaction failures: Verify callback bindings and clipboard permissions; handle unsupported environments gracefully. +- Styling conflicts: Check for CSS specificity issues and ensure theme variables are correctly scoped. +- Error states: Log diagnostic context and present actionable messages to users. + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Conclusion +ResultView serves as the central presentation component for analysis outcomes, integrating multiple specialized libraries to deliver a comprehensive, interactive, and accessible user experience. By adhering to clear prop interfaces, robust state handling, and thoughtful visualization patterns, it ensures consistent and high-quality result rendering across diverse scenarios. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Form Components.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Form Components.md new file mode 100644 index 0000000..62bde25 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Form Components.md @@ -0,0 +1,314 @@ +# Form Components + + +**Referenced Files in This Document** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document provides comprehensive documentation for form components with a focus on the ScanForm component. It explains validation patterns, user input handling, file upload processing, and form state management. It also covers the submission workflow, error handling, data transformation, prop interfaces, event handlers, and customization options to support different form scenarios. + +## Project Structure +The form-related logic is primarily implemented in the ScanForm component and integrates with application state, cloud storage, and Supabase client utilities. The following diagram shows how ScanForm fits into the broader application structure. + +```mermaid +graph TB +App["App.jsx"] --> Store["store.jsx"] +App --> ScanForm["components/ScanForm.jsx"] +ScanForm --> Cloud["lib/cloud.js"] +ScanForm --> Supabase["lib/supabase.js"] +ScanForm --> Storage["lib/storage.js"] +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [storage.js](file://src/lib/storage.js) + +## Core Components +- ScanForm: A React component that manages form state, validates inputs, handles file uploads, and submits data through cloud services. It exposes props for configuration and callbacks for lifecycle events. + +Key responsibilities: +- Maintain local form state (fields, errors, loading flags). +- Validate user inputs before submission. +- Process uploaded files (size/type checks, optional transformations). +- Submit data via cloud integration and update global store. +- Provide feedback to users via success/error states. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +## Architecture Overview +The form submission flow connects UI interactions to cloud services and persists results back into the application state. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "ScanForm.jsx" +participant Cloud as "cloud.js" +participant SB as "supabase.js" +participant Store as "store.jsx" +User->>UI : "Fill fields and select files" +UI->>UI : "Validate inputs" +UI->>Cloud : "Upload files if needed" +Cloud-->>UI : "Return file references or URLs" +UI->>SB : "Prepare payload and call API" +SB-->>UI : "Response status and data" +UI->>Store : "Update global state with result" +UI-->>User : "Show success or error feedback" +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +## Detailed Component Analysis + +### ScanForm Component +ScanForm encapsulates all form behaviors including validation, file handling, submission, and state updates. It uses hooks for local state and effects for side effects such as uploading and syncing with the backend. + +#### Prop Interfaces +- title: string — Displayed at the top of the form. +- initialData: object — Pre-populated field values. +- onSubmit: function — Callback invoked after successful submission with transformed payload. +- onError: function — Callback invoked when submission fails. +- onSuccess: function — Callback invoked upon successful submission. +- disabled: boolean — Disables interactive controls when true. +- showFileUpload: boolean — Toggles file upload section visibility. +- allowedFileTypes: array — Allowed MIME types for file uploads. +- maxFileSizeMB: number — Maximum file size in megabytes. +- requiredFields: array — Field keys that must be present and valid. +- transformPayload: function — Optional function to transform form data before submission. +- submitLabel: string — Text for the submit button. +- className: string — Additional CSS class names for styling. + +These props enable flexible customization for different scanning scenarios while keeping the core behavior consistent. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +#### State Management +- Fields: Controlled inputs bound to state; updated via change handlers. +- Errors: Per-field error messages keyed by field name. +- Loading: Boolean flag indicating active submission or upload. +- Success: Boolean flag indicating successful submission. +- Files: Array of selected files with metadata (name, type, size). + +State transitions: +- On mount: Initialize from initialData and reset errors/loading/success. +- On change: Update field value and clear corresponding error. +- On submit: Validate all fields, process files, transform payload, then submit. +- On response: Set loading false; set success true on success or populate errors on failure. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +#### Validation Patterns +- Required fields: Checked against requiredFields list. +- Type checks: Ensures numeric fields are numbers and email-like fields match expected patterns. +- File constraints: Validates allowedFileTypes and maxFileSizeMB. +- Custom rules: Extensible via transformPayload or dedicated validators passed through props. + +Validation outcomes: +- If invalid: Populate per-field errors and prevent submission. +- If valid: Proceed to file processing and submission. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +#### User Input Handling +- Change handlers: Normalize input values and update state immediately. +- Blur handlers: Trigger validation on field blur to provide early feedback. +- Keyboard shortcuts: Optional submit trigger on Enter when appropriate. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +#### File Upload Processing +- Selection: Accepts multiple files constrained by allowedFileTypes and maxFileSizeMB. +- Preview: Generates preview URLs for supported image types. +- Upload: Uses cloud service to upload files and returns references or URLs. +- Error handling: Displays specific errors for unsupported types or oversized files. + +Integration points: +- cloud.js: Handles upload requests and responses. +- supabase.js: May be used for storage endpoints depending on configuration. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +#### Submission Workflow +```mermaid +flowchart TD +Start(["Submit Click"]) --> Validate["Run Validation Rules"] +Validate --> Valid{"All Valid?"} +Valid --> |No| ShowErrors["Populate Field Errors"] +ShowErrors --> End(["Stop"]) +Valid --> |Yes| ProcessFiles["Process Selected Files"] +ProcessFiles --> HasFiles{"Any Files?"} +HasFiles --> |Yes| Upload["Upload via Cloud Service"] +Upload --> UploadOk{"Upload Success?"} +UploadOk --> |No| HandleUploadError["Set Upload Error"] +HandleUploadError --> End +UploadOk --> |Yes| BuildPayload["Build Payload with File References"] +HasFiles --> |No| BuildPayload +BuildPayload --> Transform["Apply transformPayload if provided"] +Transform --> Send["Send to Backend via Supabase"] +Send --> Response{"Response OK?"} +Response --> |No| HandleSubmitError["Set Submit Error"] +HandleSubmitError --> End +Response --> |Yes| UpdateStore["Update Global Store"] +UpdateStore --> NotifySuccess["Invoke onSuccess and Reset State"] +NotifySuccess --> End +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +#### Data Transformation +- Normalization: Converts raw inputs into a structured payload. +- Enrichment: Adds timestamps, user context, or derived fields. +- Customization: transformPayload allows scenario-specific adjustments before sending. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +#### Event Handlers and Lifecycle +- onChange: Updates field state and clears associated errors. +- onBlur: Triggers validation for immediate feedback. +- onSubmit: Orchestrates validation, file processing, submission, and state updates. +- onSuccess/onError: External callbacks for higher-level actions (navigation, analytics). + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +#### Customization Options +- Visual: className, submitLabel, title. +- Behavioral: disabled, showFileUpload, requiredFields, allowedFileTypes, maxFileSizeMB. +- Integration: onSubmit, onSuccess, onError, transformPayload. + +These options allow reusing ScanForm across different scanning workflows without duplicating logic. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +### Integration Points + +#### Application State (store.jsx) +- After successful submission, ScanForm updates global state to reflect new scan results or related entities. +- Consumers of the store can reactively render updated data. + +**Section sources** +- [store.jsx](file://src/store.jsx) + +#### Cloud Services (cloud.js) +- Provides upload functions for files. +- Returns standardized responses with file references or URLs. +- Centralizes error mapping for consistent user feedback. + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) + +#### Supabase Client (supabase.js) +- Used for API calls or storage operations depending on configuration. +- Encapsulates authentication and request formatting. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) + +#### Local Storage (storage.js) +- Optionally persists draft forms or partial submissions for recovery. +- Supports offline-first UX patterns. + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +## Dependency Analysis +The following diagram illustrates dependencies between ScanForm and supporting modules. + +```mermaid +graph LR +ScanForm["ScanForm.jsx"] --> Cloud["cloud.js"] +ScanForm --> Supabase["supabase.js"] +ScanForm --> Store["store.jsx"] +ScanForm --> Storage["storage.js"] +App["App.jsx"] --> ScanForm +App --> Store +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Debounce input changes for expensive validations or network calls. +- Lazy-load file previews only when necessary. +- Batch uploads to reduce network overhead. +- Use memoization for computed fields or derived payloads. +- Avoid unnecessary re-renders by splitting large forms into smaller sub-components. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Validation errors not clearing: Ensure change handlers reset per-field errors and that requiredFields matches actual field keys. +- File upload failures: Verify allowedFileTypes and maxFileSizeMB; check cloud service responses and map errors to user-friendly messages. +- Submission timeouts: Implement retry logic and user feedback; consider reducing payload size. +- State inconsistencies: Confirm that onSuccess resets loading and success flags and that global store updates occur after successful responses. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +## Conclusion +ScanForm provides a robust, customizable foundation for scanning workflows. Its modular design separates concerns across validation, file handling, submission, and state management. By leveraging props for configuration and callbacks for integration, it adapts to diverse scenarios while maintaining consistent user experience and reliable error handling. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Layout Components.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Layout Components.md new file mode 100644 index 0000000..1164fbd --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Layout Components.md @@ -0,0 +1,277 @@ +# Layout Components + + +**Referenced Files in This Document** +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [index.css](file://src/index.css) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the Layout component system used to structure pages, manage global chrome (header and footer), and compose content areas across routes. It covers architecture, navigation integration, responsive design patterns, styling approaches, props interfaces, and strategies for extending layouts or creating custom page wrappers. + +## Project Structure +The layout-related code is primarily implemented in a single Layout component and wired into the application entry points. Global styles are centralized in a CSS file. The following diagram shows how these files relate at a high level. + +```mermaid +graph TB +A["main.jsx
Application bootstrap"] --> B["App.jsx
Root app shell"] +B --> C["Layout.jsx
Global layout wrapper"] +C --> D["index.css
Global styles and responsive rules"] +``` + +**Diagram sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +**Section sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +## Core Components +- Layout component: Provides the global page shell including header, main content area, and footer. It composes children (page content) and applies consistent spacing, alignment, and responsive behavior. +- App shell: Initializes routing and wraps route content with the Layout component so all pages inherit the same chrome. +- Global styles: Centralized CSS that defines base typography, spacing, grid/flex utilities, and responsive breakpoints used by the layout. + +Key responsibilities: +- Render header and footer consistently across pages +- Provide a main content container with appropriate padding and max-width constraints +- Apply responsive behaviors for mobile, tablet, and desktop viewports +- Integrate with routing by wrapping route elements + +**Section sources** +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +## Architecture Overview +The layout architecture follows a simple composition pattern: +- Application bootstrap mounts the root component +- Root component sets up routing and renders an App shell +- App shell wraps all route content with the Layout component +- Layout renders header, main content area, and footer around the routed page + +```mermaid +sequenceDiagram +participant Boot as "main.jsx" +participant Root as "App.jsx" +participant Router as "Router" +participant Shell as "Layout.jsx" +participant Page as "Page Content" +Boot->>Root : Mount root component +Root->>Router : Initialize routes +Router-->>Shell : Render current route element +Shell->>Shell : Render Header +Shell->>Shell : Render Main Content Area +Shell->>Page : Render child (route content) +Shell->>Shell : Render Footer +``` + +**Diagram sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) + +## Detailed Component Analysis + +### Layout Component +Responsibilities: +- Compose header, main content area, and footer +- Enforce consistent spacing and alignment +- Apply responsive constraints (max-width, padding, grid/flex) +- Accept props to customize behavior (e.g., toggling header/footer visibility, adding sidebars) + +Props interface (typical): +- children: ReactNode — The page content to render inside the main area +- showHeader?: boolean — Whether to render the header +- showFooter?: boolean — Whether to render the footer +- className?: string — Additional class names for the root container +- maxWidth?: string | number — Max width constraint for the content area +- padding?: string | number — Padding applied to the content area + +Styling approach: +- Uses CSS classes defined in the global stylesheet +- Responsive rules via media queries in index.css +- Flexbox/Grid for layout composition + +Integration with routing: +- Wrapped around route elements in the App shell so every page inherits the layout + +Extending the layout: +- Create a higher-order wrapper that injects additional chrome (e.g., sidebar, breadcrumbs) while delegating to the base Layout +- Use conditional props to toggle sections based on route context + +```mermaid +classDiagram +class Layout { ++children ++showHeader? ++showFooter? ++className? ++maxWidth? ++padding? ++render() +} +class AppShell { ++routes ++wrapWithLayout() +} +class Styles { ++globalCSS ++responsiveRules +} +AppShell --> Layout : "wraps route content" +Layout --> Styles : "uses" +``` + +**Diagram sources** +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +**Section sources** +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +### App Shell and Routing Integration +Responsibilities: +- Initialize routing configuration +- Wrap all route elements with the Layout component +- Ensure consistent chrome across pages + +Routing flow: +- Routes resolve to page components +- Each page is rendered inside the Layout’s main content area +- Header and footer remain constant across navigations + +```mermaid +flowchart TD +Start(["Route Change"]) --> Resolve["Resolve Route Element"] +Resolve --> Wrap["Wrap with Layout"] +Wrap --> RenderHeader["Render Header"] +Wrap --> RenderMain["Render Main Content"] +RenderMain --> RenderPage["Render Page Component"] +Wrap --> RenderFooter["Render Footer"] +RenderFooter --> End(["UI Updated"]) +``` + +**Diagram sources** +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) + +**Section sources** +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) + +### Styling and Responsive Design Patterns +Approach: +- Global CSS defines base layout tokens (spacing, typography, colors) +- Media queries adjust layout for different screen sizes +- Flexbox/Grid used for composing header, main, and footer +- Max-width constraints keep content readable on large screens + +Responsive patterns: +- Mobile-first base styles +- Breakpoints for tablet and desktop +- Flexible containers that adapt to viewport width + +**Section sources** +- [index.css:1-200](file://src/index.css#L1-L200) + +### Composition Strategies and Custom Wrappers +Strategies: +- Base Layout provides core chrome; extend via wrapper components +- Conditional rendering using props to include/exclude sections +- Higher-order components can inject additional UI (e.g., breadcrumbs, sidebars) without modifying the base Layout + +Example patterns: +- AdminLayout extends Layout to add a sidebar and top navigation +- AuthenticatedLayout wraps Layout to enforce authentication state before rendering content +- MinimalLayout disables header/footer for specific flows (e.g., onboarding) + +[No sources needed since this section describes conceptual extension patterns] + +## Dependency Analysis +High-level dependencies among layout-related files: + +```mermaid +graph LR +main_jsx["main.jsx"] --> app_jsx["App.jsx"] +app_jsx --> layout_jsx["Layout.jsx"] +layout_jsx --> index_css["index.css"] +``` + +**Diagram sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +**Section sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +## Performance Considerations +- Keep Layout lightweight; avoid heavy computations in render paths +- Memoize expensive subcomponents if necessary +- Prefer CSS-based responsive rules over JS-driven layout changes +- Minimize re-renders by passing stable props and avoiding unnecessary state updates in the layout + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing global styles: Ensure index.css is imported at the application entry point +- Layout not applying: Verify the App shell wraps route elements with the Layout component +- Responsive issues: Check media query breakpoints and ensure viewport meta tag is configured +- Overflow or clipping: Confirm max-width and padding values are appropriate for target devices + +**Section sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [index.css:1-200](file://src/index.css#L1-L200) + +## Conclusion +The Layout component system provides a consistent, responsive page structure across the application. By centralizing chrome and styling, it simplifies navigation and ensures a cohesive user experience. Extensibility is achieved through props and wrapper components, enabling tailored layouts for different contexts while maintaining a unified foundation. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Props Reference +- children: ReactNode — Page content rendered within the main area +- showHeader?: boolean — Toggle header visibility +- showFooter?: boolean — Toggle footer visibility +- className?: string — Additional CSS classes for the root container +- maxWidth?: string | number — Maximum width for the content area +- padding?: string | number — Padding applied to the content area + +[No sources needed since this section lists conceptual props] + +### Example: Creating a Custom Page Wrapper +- Define a wrapper component that accepts children and additional props +- Conditionally render extra UI (e.g., sidebar) around the base Layout +- Use the wrapper in place of the base Layout for specific routes + +[No sources needed since this section describes conceptual patterns] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Utility Components.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Utility Components.md new file mode 100644 index 0000000..d3a2275 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Component System/Utility Components.md @@ -0,0 +1,263 @@ +# Utility Components + + +**Referenced Files in This Document** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the utility and helper components that power user feedback and configuration management: Toast notifications and Settings. It covers how to use these components, customize their behavior, integrate them into your application, and persist user preferences. + +## Project Structure +The relevant files for this documentation are located under src/components and src/lib: +- Toast notification component +- Settings management component +- Global store for shared state (including toast queue) +- Storage utilities for persistent settings + +```mermaid +graph TB +subgraph "Components" +T["Toast.jsx"] +S["Settings.jsx"] +end +subgraph "State & Storage" +ST["store.jsx"] +LS["lib/storage.js"] +end +T --> ST +S --> ST +S --> LS +``` + +**Diagram sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +## Core Components +- Toast: Displays transient messages with configurable positioning, duration, and message types. It integrates with a global store to manage queued notifications and auto-dismiss timers. +- Settings: Manages user preferences and configuration. It provides an interface to read/write settings and persists them using storage utilities. + +Key responsibilities: +- Toast: enqueue/dequeue notifications, render different types, control visibility and timing, handle positioning. +- Settings: load/save defaults, merge updates, expose typed getters/setters, persist changes. + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +## Architecture Overview +The system uses a simple pub/sub-like pattern via a global store for Toasts and a dedicated storage layer for Settings. + +```mermaid +sequenceDiagram +participant App as "App Code" +participant Store as "store.jsx" +participant Toast as "Toast.jsx" +participant Settings as "Settings.jsx" +participant Storage as "lib/storage.js" +App->>Store : "enqueueToast({ type, message, options })" +Store-->>Toast : "notify new toast" +Toast-->>Toast : "render with position/duration/type" +Toast-->>Store : "dismiss after timeout or manual action" +App->>Settings : "getSetting(key)" +Settings->>Storage : "read(key)" +Storage-->>Settings : "value or default" +Settings-->>App : "resolved value" +App->>Settings : "setSetting(key, value)" +Settings->>Storage : "write(key, value)" +Storage-->>Settings : "persisted" +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) + +## Detailed Component Analysis + +### Toast Notification System +Purpose: +- Provide non-blocking feedback to users through short-lived messages. +- Support multiple message types (e.g., success, error, info). +- Allow flexible positioning and duration control. + +Core concepts: +- Message types: Each toast has a type that influences styling and iconography. +- Positioning: Toasts can be anchored to corners or edges; stacking is supported. +- Duration: Auto-dismiss after a configurable time; supports manual dismissal. +- Queue: Multiple toasts can be enqueued and rendered sequentially or concurrently based on layout. + +Integration points: +- Uses a global store to maintain the current list of active toasts and actions to add/remove them. +- Renders within the app’s root container to inherit theme and layout context. + +Usage patterns: +- Show a one-off message: call the store action with a message and optional options. +- Group related messages: enqueue multiple toasts; they will stack according to position. +- Control behavior: set duration, position, and type per invocation. + +Customization options: +- Type: Determines visual style and semantics. +- Duration: Time in milliseconds before auto-dismiss. +- Position: Placement anchor (e.g., top-right, bottom-left). +- Dismiss handler: Optional callback when dismissed. + +Error handling: +- Invalid durations or positions should fall back to safe defaults. +- Duplicate messages may be coalesced to avoid clutter. + +```mermaid +flowchart TD +Start(["Show Toast"]) --> Validate["Validate inputs
type, message, options"] +Validate --> Enqueue["Enqueue in store"] +Enqueue --> Render["Render toast with position/style"] +Render --> Timer{"Auto-dismiss?"} +Timer --> |Yes| Wait["Wait for duration"] +Wait --> Dismiss["Dismiss and remove from store"] +Timer --> |No| Manual["Manual dismiss"] +Manual --> Dismiss +Dismiss --> End(["Done"]) +``` + +**Diagram sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [store.jsx](file://src/store.jsx) + +### Settings Management +Purpose: +- Centralize user preferences and application configuration. +- Provide typed accessors and setters for settings. +- Persist settings across sessions. + +Core concepts: +- Defaults: A baseline configuration object with documented keys and values. +- Merge strategy: New values override existing ones without losing unrelated keys. +- Persistence: Writes to a durable storage backend; reads with fallback to defaults. + +Integration points: +- Reads/writes via storage utilities which abstract the underlying persistence mechanism. +- Exposes a simple API for other components to get and update settings. + +Usage patterns: +- Read a setting: call the getter with a key; returns the persisted value or default. +- Update a setting: call the setter with a key/value pair; triggers persistence. +- Batch updates: provide an object to update multiple keys at once. + +Customization options: +- Default factory: Allows dynamic defaults based on environment or feature flags. +- Validation: Optional schema checks before persisting. +- Sync hooks: Optional callbacks when settings change. + +Error handling: +- Storage failures should be caught and logged; operations should degrade gracefully. +- Invalid keys or types should return defaults or throw descriptive errors. + +```mermaid +classDiagram +class Settings { ++getSetting(key) any ++setSetting(key, value) void ++updateSettings(partial) void +-defaults object +-load() void +-save() void +} +class Storage { ++get(key) any ++set(key, value) void ++remove(key) void +} +Settings --> Storage : "persists/retrieves" +``` + +**Diagram sources** +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) + +## Dependency Analysis +The following diagram shows how the components depend on shared state and storage: + +```mermaid +graph LR +App["Your App Code"] --> Store["store.jsx"] +App --> Settings["Settings.jsx"] +Toast["Toast.jsx"] --> Store +Settings --> Storage["lib/storage.js"] +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) + +## Performance Considerations +- Toast batching: Coalesce rapid successive toasts to reduce re-renders. +- Debounced saves: For frequent setting updates, debounce writes to storage to avoid excessive I/O. +- Lazy rendering: Only render visible toasts; offscreen items can be pruned. +- Minimal diffs: When updating settings, compute minimal changes and only persist deltas. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Toast not appearing: + - Ensure the store is initialized and the Toast component is mounted. + - Verify that the enqueue action is called with valid parameters. +- Toast not dismissing: + - Check duration values and timer cleanup logic. + - Confirm no long-running tasks block the UI thread. +- Settings not persisting: + - Inspect storage backend availability and permissions. + - Validate that keys exist and values match expected types. +- Conflicting settings: + - Review merge strategy and ensure partial updates do not overwrite required fields unintentionally. + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [store.jsx](file://src/store.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) + +## Conclusion +Toast and Settings are foundational utilities that improve user experience and configurability. By leveraging the global store for notifications and a robust storage-backed settings manager, you can deliver consistent feedback and reliable preference management across your application. Follow the usage patterns and customization options outlined here to integrate these components effectively. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Frontend Architecture.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Frontend Architecture.md new file mode 100644 index 0000000..15208e3 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/Frontend Architecture.md @@ -0,0 +1,551 @@ +# Frontend Architecture + + +**Referenced Files in This Document** +- [index.html](file://index.html) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/index.css](file://src/index.css) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/hooks/useCountUp.js](file://src/hooks/useCountUp.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [public/sw.js](file://public/sw.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the frontend architecture of a React-based application built with Vite. It covers the component hierarchy, custom hooks library, state management patterns, modular business logic organization, styling approach, build configuration, asset optimization, and development workflow. It also includes diagrams for component interactions, data binding patterns, performance strategies, responsive design implementation, and cross-browser considerations. + +## Project Structure +The frontend is organized into clear layers: +- Entry points and runtime bootstrap +- Application shell and routing +- Feature components under src/components +- Custom hooks under src/hooks +- Business logic modules under src/lib +- Global styles under src/index.css +- Build and deployment configuration at the repository root + +```mermaid +graph TB +HTML["index.html"] --> MainJS["src/main.jsx"] +MainJS --> AppJS["src/App.jsx"] +AppJS --> StoreJS["src/store.jsx"] +AppJS --> AuthJS["src/auth.jsx"] +AppJS --> MobileJS["src/mobile.js"] +AppJS --> Layout["src/components/Layout.jsx"] +Layout --> Pages["Feature Components
src/components/*"] +Pages --> Hooks["Custom Hooks
src/hooks/*"] +Pages --> Lib["Business Logic
src/lib/*"] +Lib --> Supabase["src/lib/supabase.js"] +Lib --> Storage["src/lib/storage.js"] +Lib --> AI["src/lib/ai.js"] +Lib --> Billing["src/lib/billing.js"] +Lib --> Entitlement["src/lib/entitlement.js"] +Lib --> Scoring["src/lib/scoring.js"] +Lib --> Stats["src/lib/stats.js"] +Lib --> Followups["src/lib/followups.js"] +Lib --> Redflags["src/lib/redflags.js"] +Lib --> Sync["src/lib/sync.js"] +CSS["src/index.css"] --> AppJS +SW["public/sw.js"] --> HTML +``` + +**Diagram sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/index.css](file://src/index.css) +- [public/sw.js](file://public/sw.js) + +**Section sources** +- [index.html](file://index.html) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/index.css](file://src/index.css) +- [public/sw.js](file://public/sw.js) + +## Core Components +- Application Shell + - The root entry initializes the React app and mounts it to the DOM. + - The application shell sets up global providers (e.g., auth, store), routes, and layout. +- Layout + - Provides consistent chrome across pages (header, sidebar, content area). + - Composes page-level components and shared UI elements. +- Feature Pages + - AccountPage: user account overview and settings navigation. + - AiAssistant: interface for AI-driven assistance flows. + - MockInterviewPage: end-to-end interview simulation flow. + - OffersPage: display and management of offers. + - ResultView: presentation of analysis or scoring results. + - ScanForm: form for scanning or inputting data. + - Settings: application preferences and configuration. + - Toast: non-intrusive notifications. + - Tracker: tracking or monitoring features. +- State Management + - Centralized store module provides reactive state and actions consumed by components. +- Authentication + - Auth integration handles session lifecycle and guards protected routes. +- Mobile Integration + - Mobile-specific initialization and capabilities are wired via mobile.js. + +**Section sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) + +## Architecture Overview +High-level runtime flow from browser to feature components and business logic: + +```mermaid +sequenceDiagram +participant Browser as "Browser" +participant HTML as "index.html" +participant Main as "src/main.jsx" +participant App as "src/App.jsx" +participant Store as "src/store.jsx" +participant Auth as "src/auth.jsx" +participant Layout as "src/components/Layout.jsx" +participant Page as "src/components/*" +participant Lib as "src/lib/*" +participant SW as "public/sw.js" +Browser->>HTML : Load page +HTML->>Main : Import bootstrap +Main->>App : Render root +App->>Store : Initialize store +App->>Auth : Initialize auth +App->>Layout : Render layout +Layout->>Page : Render current page +Page->>Lib : Call business logic +Lib-->>Page : Return data/results +Page-->>Layout : Update UI +SW-->>Browser : Service worker events +``` + +**Diagram sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [public/sw.js](file://public/sw.js) + +## Detailed Component Analysis + +### Component Hierarchy and Composition +- Root composition + - main.jsx bootstraps React and renders App. + - App.jsx composes providers (store, auth), routes, and Layout. +- Layout composition + - Layout.jsx wraps pages with shared chrome and navigational context. +- Page composition + - Each page composes reusable subcomponents (forms, tables, charts) and consumes hooks and lib modules. + +```mermaid +classDiagram +class Main { ++bootstrap() +} +class App { ++render() +} +class Store { ++state ++actions +} +class Auth { ++session ++login() ++logout() +} +class Layout { ++Header ++Sidebar ++Content +} +class Pages { ++AccountPage ++AiAssistant ++MockInterviewPage ++OffersPage ++ResultView ++ScanForm ++Settings ++Toast ++Tracker +} +Main --> App : "renders" +App --> Store : "consumes" +App --> Auth : "consumes" +App --> Layout : "wraps" +Layout --> Pages : "renders" +``` + +**Diagram sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) + +### Custom Hooks Library +- useCountUp + - Purpose: drives animated counters used in dashboards or result views. + - Typical usage: invoked within components to animate numeric transitions based on props or derived values. + +```mermaid +flowchart TD +Start(["Component renders"]) --> HookCall["useCountUp(targetValue, options)"] +HookCall --> Compute["Compute delta and duration"] +Compute --> Animate["Request animation frames"] +Animate --> UpdateState["Update displayed value"] +UpdateState --> Done(["Animation complete"]) +``` + +**Diagram sources** +- [src/hooks/useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [src/hooks/useCountUp.js](file://src/hooks/useCountUp.js) + +### State Management Patterns +- Centralized store + - Provides a single source of truth for UI and domain state. + - Exposes state slices and action creators consumed by components. +- Data binding + - Components subscribe to store slices and dispatch actions to mutate state. + - Derived values can be computed in components or via lightweight selectors. + +```mermaid +sequenceDiagram +participant Comp as "Component" +participant Store as "src/store.jsx" +participant UI as "React UI" +Comp->>Store : Subscribe(stateSlice) +Store-->>Comp : stateSlice +Comp->>UI : render(stateSlice) +Comp->>Store : dispatch(action) +Store->>Store : reducer/update +Store-->>Comp : new stateSlice +Comp->>UI : re-render +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) + +**Section sources** +- [src/store.jsx](file://src/store.jsx) + +### Business Logic Modules (lib) +The lib directory encapsulates domain logic and integrations: +- supabase.js: client setup and queries/mutations against Supabase. +- storage.js: local persistence helpers (e.g., localStorage/sessionStorage wrappers). +- ai.js: orchestration for AI assistant calls and prompts. +- billing.js: checkout and subscription-related operations. +- entitlement.js: feature gating and access control checks. +- scoring.js: scoring algorithms and transformations. +- stats.js: statistics aggregation and summaries. +- followups.js: scheduling and reminders logic. +- redflags.js: detection and reporting of risk indicators. +- sync.js: synchronization between local state and remote services. + +```mermaid +graph LR +Pages["Feature Components"] --> Lib["src/lib/*"] +Lib --> Supabase["supabase.js"] +Lib --> Storage["storage.js"] +Lib --> AI["ai.js"] +Lib --> Billing["billing.js"] +Lib --> Entitlement["entitlement.js"] +Lib --> Scoring["scoring.js"] +Lib --> Stats["stats.js"] +Lib --> Followups["followups.js"] +Lib --> Redflags["redflags.js"] +Lib --> Sync["sync.js"] +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +### Styling Approach +- Global stylesheet + - index.css defines base styles, typography, and layout primitives. +- Component-level styling + - Components may import CSS modules or rely on global classes; ensure consistent naming conventions and avoid style duplication. +- Responsive design + - Use fluid layouts, media queries, and flexible units to support multiple screen sizes. + - Prefer relative sizing and spacing tokens for consistency. + +**Section sources** +- [src/index.css](file://src/index.css) + +### Build Configuration with Vite +- Development server and hot module replacement (HMR) + - Configured via vite.config.js for fast feedback loops. +- Asset optimization + - Production builds optimize assets (images, fonts) and minify code. +- Environment variables + - Access via import.meta.env.* in Vite. +- Deployment targets + - netlify.toml and vercel.json define hosting configurations. + +```mermaid +flowchart TD +Dev["npm run dev"] --> Vite["Vite Dev Server"] +Vite --> HMR["Hot Module Replacement"] +Prod["npm run build"] --> ViteBuild["Vite Build"] +ViteBuild --> Assets["Asset Optimization"] +ViteBuild --> Bundle["Code Splitting & Minification"] +Assets --> Deploy["Deploy (Netlify/Vercel)"] +Bundle --> Deploy +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +### Service Worker and Offline Support +- public/sw.js registers a service worker for caching and offline behavior. +- Integrate with PWA manifest and cache strategies appropriate for your app’s needs. + +**Section sources** +- [public/sw.js](file://public/sw.js) + +## Dependency Analysis +Frontend dependency graph focusing on runtime relationships: + +```mermaid +graph TB +Main["src/main.jsx"] --> App["src/App.jsx"] +App --> Store["src/store.jsx"] +App --> Auth["src/auth.jsx"] +App --> Mobile["src/mobile.js"] +App --> Layout["src/components/Layout.jsx"] +Layout --> C_Account["src/components/AccountPage.jsx"] +Layout --> C_AI["src/components/AiAssistant.jsx"] +Layout --> C_Interview["src/components/MockInterviewPage.jsx"] +Layout --> C_Offers["src/components/OffersPage.jsx"] +Layout --> C_Result["src/components/ResultView.jsx"] +Layout --> C_Scan["src/components/ScanForm.jsx"] +Layout --> C_Settings["src/components/Settings.jsx"] +Layout --> C_Toast["src/components/Toast.jsx"] +Layout --> C_Tracker["src/components/Tracker.jsx"] +C_Account --> Libs["src/lib/*"] +C_AI --> Libs +C_Interview --> Libs +C_Offers --> Libs +C_Result --> Libs +C_Scan --> Libs +C_Settings --> Libs +C_Toast --> Libs +C_Tracker --> Libs +``` + +**Diagram sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +**Section sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/sync.js](file://src/lib/sync.js) + +## Performance Considerations +- Code splitting and lazy loading + - Route-level and component-level lazy imports to reduce initial bundle size. +- Memoization + - Use memoization for expensive computations and stable references in components. +- Efficient rendering + - Avoid unnecessary re-renders by keeping state granular and using derived values judiciously. +- Asset optimization + - Leverage Vite’s production optimizations for images, fonts, and static assets. +- Network efficiency + - Cache responses where appropriate; batch requests when possible. +- Service worker caching + - Strategically cache critical assets for faster subsequent loads. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +- Common issues + - Authentication failures: verify session handling and token refresh flows. + - Store inconsistencies: ensure actions update state immutably and subscribers receive updates. + - API errors: centralize error handling in lib modules and surface user-friendly messages via Toast. + - Service worker conflicts: clear caches during development if stale assets persist. +- Debugging tips + - Use browser dev tools to inspect network requests and store state changes. + - Log key transitions in hooks and lib functions during development. + +**Section sources** +- [src/auth.jsx](file://src/auth.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/components/Toast.jsx](file://src/components/Toast.jsx) +- [public/sw.js](file://public/sw.js) + +## Conclusion +The frontend follows a clean separation of concerns: a thin bootstrap layer, a composed application shell, feature-focused components, and a well-organized lib layer for business logic. State is centralized and declaratively bound to components, while Vite provides a fast development experience and optimized production builds. Responsive design and cross-browser compatibility are achieved through modern CSS practices and progressive enhancement via the service worker. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Build and Development Workflow +- Local development + - Start the dev server for instant feedback and HMR. +- Building for production + - Generate optimized bundles and assets. +- Deployment + - Configure hosting platforms using provided configuration files. + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +### Cross-Browser Compatibility +- Polyfills and feature detection + - Ensure core APIs used in hooks and lib modules are polyfilled or guarded for older browsers. +- CSS compatibility + - Test layout and animations across major browsers; prefer widely supported properties. +- Service worker support + - Gracefully degrade functionality when service workers are unavailable. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/State Management.md b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/State Management.md new file mode 100644 index 0000000..572c1f5 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Frontend Architecture/State Management.md @@ -0,0 +1,408 @@ +# State Management + + +**Referenced Files in This Document** +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [main.jsx](file://src/main.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the state management architecture, focusing on: +- A custom store implementation for global application state +- Context-based state sharing across components +- Local storage persistence strategies +- The useCountUp hook and patterns for building custom hooks +- Authentication state flow +- Data synchronization between local and cloud storage +- State persistence mechanisms +- Guidance for creating new hooks and managing complex state interactions + +The goal is to provide both a high-level understanding and actionable details for extending and maintaining the system. + +## Project Structure +State-related code is organized into focused modules: +- Store and context providers at the application root +- Authentication state and flows +- Storage utilities for local persistence +- Cloud integration and sync orchestration +- Custom hooks for reusable logic + +```mermaid +graph TB +subgraph "App Root" +Main["main.jsx"] +Store["store.jsx"] +Auth["auth.jsx"] +end +subgraph "Lib" +Storage["lib/storage.js"] +Cloud["lib/cloud.js"] +Sync["lib/sync.js"] +Supabase["lib/supabase.js"] +end +subgraph "Hooks" +CountUp["hooks/useCountUp.js"] +end +Main --> Store +Main --> Auth +Store --> Storage +Store --> Sync +Sync --> Cloud +Cloud --> Supabase +CountUp --> Storage +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Core Components +- Custom store: Provides a centralized state container with subscribe/update semantics and optional persistence. It exposes a provider that wraps the app so consumers can read and update state via context or direct subscriptions. +- Context-based sharing: React context is used to distribute store state and actions throughout the component tree without prop drilling. +- Local storage persistence: A storage adapter persists selected slices of state to localStorage and hydrates them on startup. +- Cloud sync: An orchestrator coordinates syncing between local state and remote data sources (e.g., Supabase), handling conflicts and offline scenarios. +- Authentication state: A dedicated module manages user session state, login/logout flows, and integrates with the store and sync layer. +- Custom hooks: Reusable logic such as useCountUp encapsulates stateful behavior and side effects, demonstrating best practices for composing hooks. + +Key responsibilities: +- Store: state shape, updates, subscriptions, hydration +- Auth: session lifecycle, token/session persistence, auth-aware sync triggers +- Storage: typed reads/writes, error handling, schema versioning +- Sync: conflict resolution, backoff, idempotency +- Hooks: predictable state transitions, memoization, cleanup + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Architecture Overview +The state architecture follows a unidirectional data flow with clear boundaries: +- UI components dispatch actions or call store methods +- Store updates state and persists locally +- Sync layer observes changes and reconciles with cloud storage +- Auth state gates access and influences sync behavior + +```mermaid +sequenceDiagram +participant UI as "Components" +participant Store as "Custom Store" +participant Storage as "Local Storage" +participant Sync as "Sync Orchestrator" +participant Cloud as "Cloud Client" +participant DB as "Supabase" +UI->>Store : "update(statePath, value)" +Store->>Storage : "persist(key, snapshot)" +Store-->>UI : "notify subscribers" +Store->>Sync : "emit change event" +Sync->>Cloud : "push(delta/patch)" +Cloud->>DB : "write/read" +DB-->>Cloud : "result" +Cloud-->>Sync : "ack/merge" +Sync-->>Store : "apply remote changes" +Store->>Storage : "persist updated state" +Store-->>UI : "notify subscribers" +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Custom Store Implementation +Responsibilities: +- Maintain a single source of truth for application state +- Provide subscribe/unsubscribe for efficient reactivity +- Offer update functions with path-based mutations +- Persist and hydrate state from local storage +- Integrate with sync events to reconcile with cloud + +Design considerations: +- Immutability-friendly updates to avoid unnecessary re-renders +- Debounced or batched writes for performance +- Versioned storage keys to support migrations +- Error boundaries around persistence operations + +Typical usage: +- Initialize store with default state and persistence config +- Wrap app with store provider +- Read state via context or subscription +- Update state through store actions + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +### Context-Based State Sharing +React context distributes store state and actions: +- Provider injects store instance into the tree +- Consumers subscribe to relevant slices to minimize re-renders +- Actions are exposed as stable references to avoid churn + +Best practices: +- Split contexts by domain if needed (e.g., auth vs. feature state) +- Memoize derived values where appropriate +- Avoid over-subscribing large trees; prefer targeted selectors + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [main.jsx](file://src/main.jsx) + +### Local Storage Persistence Strategies +Persistence layer: +- Serializes state snapshots to localStorage +- Hydrates state on app start +- Handles parse errors and fallback defaults +- Supports partial persistence (only selected keys) + +Operational notes: +- Use unique keys per feature or entity +- Implement versioning for schema evolution +- Guard against quota exceeded and serialization failures + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +### useCountUp Hook Implementation +Purpose: +- Encapsulate an incrementing counter with controlled state and optional persistence +- Demonstrate composition of local storage and effect lifecycles + +Behavior highlights: +- Initializes count from storage or default +- Exposes increment/reset actions +- Persists count changes with debouncing or explicit commits +- Cleans up listeners on unmount + +Extensibility: +- Accept options for key, initial value, and persistence strategy +- Return both state and action handlers for clarity + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) + +### Authentication State Flow +Auth module manages: +- Session detection and initialization +- Login/logout workflows +- Token/session persistence +- Integration with store and sync to gate features and trigger data sync + +Flow overview: +- On app start, check persisted session +- If present, validate and hydrate user state +- On login, persist session and trigger sync +- On logout, clear session and optionally purge sensitive local state + +```mermaid +flowchart TD +Start(["App Start"]) --> CheckSession["Check persisted session"] +CheckSession --> HasSession{"Valid session?"} +HasSession --> |Yes| HydrateUser["Hydrate user state"] +HasSession --> |No| ShowGuest["Show guest state"] +HydrateUser --> EnableSync["Enable sync for authenticated data"] +EnableSync --> Ready(["Ready"]) +ShowGuest --> Ready +Ready --> LoginAction["Login action"] +LoginAction --> PersistSession["Persist session"] +PersistSession --> HydrateUser +Ready --> LogoutAction["Logout action"] +LogoutAction --> ClearSession["Clear session and sensitive state"] +ClearSession --> ShowGuest +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +### Data Synchronization Between Local and Cloud Storage +Sync orchestrator: +- Observes store changes and queues operations +- Applies remote changes and resolves conflicts +- Manages connectivity and retry/backoff +- Ensures idempotent writes and consistent merges + +Conflict resolution strategies: +- Last-write-wins with timestamps +- Field-level merging for structured objects +- User prompts for manual resolution when necessary + +Offline-first approach: +- Queue mutations while offline +- Replay queue on reconnect +- Graceful degradation with cached data + +**Section sources** +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +### State Persistence Mechanisms +Mechanisms: +- Snapshot-based persistence for simple structures +- Delta-based persistence for large datasets +- Selective persistence to reduce storage footprint +- Migration helpers for evolving schemas + +Reliability: +- Try/catch around all I/O +- Fallback to defaults on corruption +- Background retries for transient failures + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis +High-level dependencies among state modules: + +```mermaid +graph LR +Store["store.jsx"] --> Storage["storage.js"] +Store --> Sync["sync.js"] +Sync --> Cloud["cloud.js"] +Cloud --> Supabase["supabase.js"] +Auth["auth.jsx"] --> Store +Auth --> Storage +Auth --> Sync +CountUp["useCountUp.js"] --> Storage +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [auth.jsx](file://src/auth.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [auth.jsx](file://src/auth.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Performance Considerations +- Prefer selective subscriptions to avoid full-tree re-renders +- Batch multiple updates before persisting to reduce I/O +- Use stable references for actions and context values +- Debounce frequent writes and throttle network requests +- Keep state normalized to simplify diffs and merges +- Avoid deep object cloning; use immutable updates or structural sharing + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Persistence failures: Validate JSON serialization, handle quota exceeded, and ensure migration paths exist +- Sync conflicts: Inspect timestamps and merge rules; add logging around conflict points +- Auth loops: Verify session validation and guard against repeated refresh cycles +- Memory leaks: Ensure unsubscribe and cleanup in hooks and providers +- Stale data: Confirm that subscribers receive latest state after hydration + +Diagnostic tips: +- Log state deltas around updates and sync events +- Add checkpoints around persistence and network calls +- Use feature flags to toggle verbose logging in development + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) + +## Conclusion +The state management architecture centers on a custom store with context-based distribution, robust local persistence, and a sync layer for cloud reconciliation. Authentication state integrates seamlessly with these layers to enable secure, offline-first experiences. By following the patterns outlined here—especially around selective subscriptions, idempotent sync, and resilient persistence—you can extend the system confidently and maintain predictable state behavior across the application. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Creating New Hooks: Patterns and Examples +Guidelines: +- Define clear inputs and outputs; keep hooks pure where possible +- Encapsulate side effects (I/O, timers) within the hook +- Persist only what is necessary and debounce writes +- Provide sensible defaults and configuration options +- Test hooks in isolation using minimal setups + +Example pattern: useCountUp +- Initializes from storage or default +- Exposes increment/reset actions +- Persists changes reliably +- Cleans up resources on unmount + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) + +### Managing Complex State Interactions +Recommendations: +- Normalize state to reduce duplication and simplify updates +- Use domain-scoped contexts or sub-stores for large applications +- Centralize conflict resolution and merge strategies in the sync layer +- Instrument critical paths with logging and metrics +- Write tests for state transitions, persistence, and sync edge cases + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/Integration Patterns.md b/.qoder/repowiki/en/content/Architecture Overview/Integration Patterns.md new file mode 100644 index 0000000..29fff95 --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/Integration Patterns.md @@ -0,0 +1,440 @@ +# Integration Patterns + + +**Referenced Files in This Document** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) +- [ai.js](file://src/lib/ai.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Security Considerations](#security-considerations) +9. [Monitoring and Observability](#monitoring-and-observability) +10. [Troubleshooting Guide](#troubleshooting-guide) +11. [Conclusion](#conclusion) + +## Introduction +This document describes the external integration patterns for AI services, payment processing (PayMongo and PayPal), and webhook handling. It focuses on API client patterns, retry strategies, error handling, subscription billing lifecycle, order fulfillment, authentication flows, data transformation, security considerations, rate limiting, and monitoring strategies for third-party dependencies. + +## Project Structure +The integration surface is split between: +- Serverless functions (Supabase Functions) that act as secure proxies to third-party APIs and handle webhooks +- Shared libraries for HTTP transport and domain-specific clients (e.g., PayPal) +- Frontend libraries that orchestrate user flows and call serverless endpoints + +```mermaid +graph TB +subgraph "Frontend" +FE_Billing["billing.js"] +FE_AI["ai.js"] +end +subgraph "Supabase Functions" +FC_CreateCheckout["create-checkout/index.ts"] +FC_PaymongoWebhook["paymongo-webhook/index.ts"] +FC_CancelSub["cancel-subscription/index.ts"] +FC_AIProxy["ai-proxy/index.ts"] +FC_PP_CreateOrder["create-paypal-order/index.ts"] +FC_PP_CaptureOrder["capture-paypal-order/index.ts"] +FC_PP_Webhook["paypal-webhook/index.ts"] +SH_HTTP["_shared/http.ts"] +SH_PP["_shared/paypal.ts"] +SH_PP_RT["_shared/paypal-runtime.ts"] +SH_Entitlement["_shared/entitlement.ts"] +end +subgraph "External Services" +PayMongo["PayMongo API"] +PayPal["PayPal API"] +AIProvider["AI Provider API"] +end +FE_Billing --> FC_CreateCheckout +FC_CreateCheckout --> PayMongo +PayMongo -- "webhook" --> FC_PaymongoWebhook +FE_Billing --> FC_PP_CreateOrder +FC_PP_CreateOrder --> PayPal +PayPal -- "webhook" --> FC_PP_Webhook +FE_Billing --> FC_PP_CaptureOrder +FC_PP_CaptureOrder --> PayPal +FE_AI --> FC_AIProxy +FC_AIProxy --> AIProvider +FC_CreateCheckout --> SH_HTTP +FC_PaymongoWebhook --> SH_HTTP +FC_PP_CreateOrder --> SH_PP +FC_PP_CaptureOrder --> SH_PP +FC_PP_Webhook --> SH_PP +FC_PP_CreateOrder --> SH_PP_RT +FC_PP_CaptureOrder --> SH_PP_RT +FC_PaymongoWebhook --> SH_Entitlement +FC_PP_Webhook --> SH_Entitlement +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) +- [ai.js](file://src/lib/ai.js) + +**Section sources** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + +## Core Components +- HTTP transport layer: Centralized request/response handling, headers, timeouts, retries, and error normalization used by all integrations. +- PayPal client: Encapsulates PayPal SDK/runtime configuration, order creation, capture, and webhook signature verification. +- Entitlements: Applies feature access based on subscription status and plan attributes. +- Billing orchestration: Frontend library coordinates checkout and order flows with serverless endpoints. +- AI proxy: Securely forwards prompts to the AI provider with credentials and response mapping. + +Key responsibilities: +- Authentication and signing for outbound calls +- Idempotency and deduplication for webhooks +- Robust error handling and retry policies +- Data transformation between internal models and provider payloads + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) +- [ai.js](file://src/lib/ai.js) + +## Architecture Overview +The system uses a thin frontend that delegates sensitive operations to serverless functions. These functions authenticate to third-party providers, transform payloads, persist state, and emit events or update entitlements. Webhooks are handled idempotently to ensure consistent state. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Billing as "billing.js" +participant Checkout as "create-checkout/index.ts" +participant PayMongo as "PayMongo API" +participant Webhook as "paymongo-webhook/index.ts" +participant Entitle as "entitlement.ts" +Client->>Billing : "Initiate checkout" +Billing->>Checkout : "POST /create-checkout" +Checkout->>PayMongo : "Create payment link/session" +PayMongo-->>Checkout : "Payment URL + metadata" +Checkout-->>Billing : "Redirect URL" +Note over Client,Billing : "User completes payment externally" +PayMongo-->>Webhook : "Event payload" +Webhook->>Entitle : "Update entitlements" +Entitle-->>Webhook : "Result" +Webhook-->>PayMongo : "200 OK" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### AI Service Integration +The AI integration follows a proxy pattern to keep secrets off the client and normalize responses. The frontend sends requests to a dedicated function which authenticates to the AI provider and returns structured results. + +```mermaid +sequenceDiagram +participant UI as "UI" +participant AILib as "ai.js" +participant Proxy as "ai-proxy/index.ts" +participant Provider as "AI Provider API" +UI->>AILib : "Generate response" +AILib->>Proxy : "POST /ai-proxy {prompt, options}" +Proxy->>Provider : "Authenticated request" +Provider-->>Proxy : "Streamed or final response" +Proxy-->>AILib : "Normalized result" +AILib-->>UI : "Render output" +``` + +**Diagram sources** +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + +### PayMongo Subscription Billing +The PayMongo flow creates a checkout session, redirects the user, and updates entitlements upon successful payment via webhook. Cancellation is supported through a dedicated endpoint. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Billing as "billing.js" +participant Create as "create-checkout/index.ts" +participant PM as "PayMongo API" +participant WH as "paymongo-webhook/index.ts" +participant Ent as "entitlement.ts" +Client->>Billing : "Start subscription" +Billing->>Create : "POST /create-checkout" +Create->>PM : "Create checkout" +PM-->>Create : "Checkout URL" +Create-->>Billing : "URL" +Billing-->>Client : "Redirect" +PM-->>WH : "Payment succeeded event" +WH->>Ent : "Grant entitlements" +Ent-->>WH : "Updated state" +WH-->>PM : "Acknowledge" +``` + +Cancellation flow: + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Cancel as "cancel-subscription/index.ts" +participant PM as "PayMongo API" +Client->>Cancel : "Cancel subscription" +Cancel->>PM : "Cancel subscription" +PM-->>Cancel : "Cancellation confirmed" +Cancel-->>Client : "Status updated" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +### PayPal Order Lifecycle and Fulfillment +PayPal integration includes order creation, capture, and webhook-driven fulfillment. The shared PayPal client abstracts runtime configuration and API calls. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Billing as "billing.js" +participant PPCreate as "create-paypal-order/index.ts" +participant PPCap as "capture-paypal-order/index.ts" +participant PPWebhook as "paypal-webhook/index.ts" +participant PPAPI as "PayPal API" +participant Ent as "entitlement.ts" +Client->>Billing : "Start PayPal checkout" +Billing->>PPCreate : "POST /create-paypal-order" +PPCreate->>PPAPI : "Create order" +PPAPI-->>PPCreate : "Order ID + approval URL" +PPCreate-->>Billing : "Approval URL" +Billing-->>Client : "Redirect to approve" +Client->>PPCap : "POST /capture-paypal-order" +PPCap->>PPAPI : "Capture order" +PPAPI-->>PPCap : "Captured" +PPAPI-->>PPWebhook : "Payment completed event" +PPWebhook->>Ent : "Grant entitlements" +Ent-->>PPWebhook : "Updated state" +PPWebhook-->>PPAPI : "Acknowledge" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### API Client Patterns and Retry Strategies +A centralized HTTP client standardizes: +- Request construction and header management +- Timeout and cancellation semantics +- Retry policy with exponential backoff and jitter +- Error classification and normalized responses +- Idempotency keys where applicable + +```mermaid +flowchart TD +Start(["HTTP Call Entry"]) --> Build["Build request
headers, body, idempotency key"] +Build --> Attempt{"Attempt < max?"} +Attempt --> |No| Fail["Return normalized error"] +Attempt --> |Yes| Send["Send request"] +Send --> Resp{"Response status"} +Resp --> |Success| Return["Normalize and return"] +Resp --> |Retryable| Backoff["Compute backoff + jitter"] +Backoff --> Wait["Wait"] +Wait --> Attempt +Resp --> |Non-retryable| Fail +``` + +**Diagram sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Webhook Handling Mechanisms +Webhooks must be verified, parsed, deduplicated, and processed idempotently. Both PayMongo and PayPal handlers follow similar patterns: +- Validate signatures or use platform verification +- Parse event payload and extract entity IDs +- Check local state to avoid duplicate processing +- Apply business changes (e.g., grant entitlements) +- Acknowledge receipt + +```mermaid +flowchart TD +WStart(["Webhook Received"]) --> Verify["Verify signature/auth"] +Verify --> Valid{"Valid?"} +Valid --> |No| Reject["Reject and log"] +Valid --> |Yes| Dedup["Check idempotency store"] +Dedup --> Seen{"Already processed?"} +Seen --> |Yes| Ack["Acknowledge and exit"] +Seen --> |No| Transform["Transform to internal model"] +Transform --> Apply["Apply changes (e.g., entitlements)"] +Apply --> Persist["Persist outcome"] +Persist --> Ack["Acknowledge"] +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Dependency Analysis +The following diagram shows how components depend on each other and external services. + +```mermaid +graph LR +FE_Billing["billing.js"] --> FC_Checkout["create-checkout/index.ts"] +FE_Billing --> FC_PP_Create["create-paypal-order/index.ts"] +FE_Billing --> FC_PP_Capture["capture-paypal-order/index.ts"] +FE_AI["ai.js"] --> FC_AIProxy["ai-proxy/index.ts"] +FC_Checkout --> SH_HTTP["_shared/http.ts"] +FC_Checkout --> PayMongo["PayMongo API"] +FC_PP_Create --> SH_PP["_shared/paypal.ts"] +FC_PP_Create --> SH_PP_RT["_shared/paypal-runtime.ts"] +FC_PP_Create --> PayPal["PayPal API"] +FC_PP_Capture --> SH_PP +FC_PP_Capture --> PayPal +FC_PP_Webhook["paypal-webhook/index.ts"] --> SH_PP +FC_PP_Webhook --> Entitlement["_shared/entitlement.ts"] +FC_PM_Webhook["paymongo-webhook/index.ts"] --> SH_HTTP +FC_PM_Webhook --> Entitlement +FC_Cancel["cancel-subscription/index.ts"] --> SH_HTTP +FC_Cancel --> PayMongo +FC_AIProxy --> AIProv["AI Provider API"] +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [ai.js](file://src/lib/ai.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [ai.js](file://src/lib/ai.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Performance Considerations +- Use connection pooling and reuse clients where possible to reduce handshake overhead. +- Prefer streaming responses for long-running AI calls to improve perceived latency. +- Implement circuit breakers around third-party calls to fail fast during outages. +- Cache static configuration (e.g., PayPal client settings) at function startup. +- Batch or coalesce idempotent writes when processing high-volume webhooks. + +[No sources needed since this section provides general guidance] + +## Security Considerations +- Store secrets in environment variables; never hardcode credentials. +- Verify webhook signatures using provider-provided algorithms and secret values. +- Enforce least privilege for service accounts and API keys. +- Validate and sanitize all inbound payloads before processing. +- Use HTTPS-only communication and enforce TLS versions. +- Implement idempotency keys for create and capture operations to prevent double-charging. +- Restrict IP ranges or origins if supported by providers. + +[No sources needed since this section provides general guidance] + +## Monitoring and Observability +- Log structured events for each integration step (request, response, errors). +- Track success/failure rates, latency percentiles, and retry counts per provider. +- Emit metrics for webhook processing time and deduplication hits. +- Alert on sustained error spikes, signature verification failures, and timeout increases. +- Correlate logs across frontend, serverless functions, and provider dashboards. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Webhook not received: Ensure public URLs are configured and DNS resolves correctly; verify provider’s delivery logs. +- Signature verification failed: Confirm secret values and algorithm match provider documentation; check timezone and clock skew. +- Duplicate processing: Verify idempotency checks and unique constraints in storage. +- Payment captured but entitlement not granted: Inspect post-capture steps and transaction boundaries; add compensating actions. +- Rate limited by provider: Reduce concurrency, implement backoff, and queue retries. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +The integration architecture centralizes sensitive operations in serverless functions, standardizes HTTP behavior, and enforces robust error handling and idempotency. PayMongo and PayPal flows are clearly separated into creation, capture, and webhook stages, while the AI proxy secures provider interactions. With proper security, observability, and resilience measures, the system can reliably manage subscriptions and fulfill orders across multiple providers. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Architecture Overview/System Architecture.md b/.qoder/repowiki/en/content/Architecture Overview/System Architecture.md new file mode 100644 index 0000000..b87408d --- /dev/null +++ b/.qoder/repowiki/en/content/Architecture Overview/System Architecture.md @@ -0,0 +1,571 @@ +# System Architecture + + +**Referenced Files in This Document** +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [storage.js](file://src/lib/storage.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [OfferPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [index.html](file://index.html) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [package.json](file://package.json) +- [config.toml](file://supabase/config.toml) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [prompt.ts](file://supabase/functions/_shared/prompts.ts) +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [sw.js](file://public/sw.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Security Architecture](#security-architecture) +9. [Scalability and Deployment Topology](#scalability-and-deployment-topology) +10. [Troubleshooting Guide](#troubleshooting-guide) +11. [Conclusion](#conclusion) + +## Introduction +This document describes the system architecture for ApplyGuard PH, a web-first application with mobile packaging via Capacitor. It focuses on component-based UI design, service-layer separation, state management strategy, data flow from local storage to cloud synchronization, and integration points with Supabase Functions for billing and AI proxying. The goal is to provide both high-level architectural insights and code-level references for developers and operators. + +## Project Structure +The project follows a feature-oriented layout: +- src/components: React components for user-facing features (account, settings, tracker, scan form, AI assistant, offers, results). +- src/lib: Service layer modules for storage, sync, cloud communication, entitlements, billing, and domain logic. +- supabase/functions: Serverless functions for billing flows, webhook handling, AI proxy, and shared utilities. +- supabase/migrations: Database schema and migration scripts. +- public: PWA assets including manifest and service worker. +- Root configuration files for build, deployment, and runtime behavior. + +```mermaid +graph TB +subgraph "Frontend" +A["React App
src/main.jsx"] +B["Components
src/components/*"] +C["Service Layer
src/lib/*"] +D["State Store
src/store.jsx"] +end +subgraph "Supabase Platform" +E["Postgres DB
migrations/*"] +F["Edge Functions
supabase/functions/*"] +end +subgraph "External Services" +G["Payment Gateways
PayPal / PayMongo"] +H["AI Provider API"] +end +A --> B +B --> C +C --> D +C --> E +C --> F +F --> G +F --> H +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) + +## Core Components +- Application shell and routing: + - Entry point initializes the app and mounts the root component. + - Layout component provides consistent structure across pages. +- Feature components: + - Account and Settings manage user profile and preferences. + - Tracker and ScanForm handle core scanning workflows. + - AiAssistant integrates AI capabilities through server-side proxy. + - Offers and ResultView present outcomes and related actions. +- State management: + - Centralized store coordinates UI state and persistence hooks. +- Service layer: + - Storage module abstracts local persistence. + - Sync module orchestrates conflict resolution and real-time updates. + - Cloud module encapsulates Supabase client usage and function calls. + - Entitlement and Billing modules implement subscription checks and checkout flows. + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +ApplyGuard PH uses a component-based frontend with a clear service-layer separation. Data flows from user interactions into local storage, then synchronizes with Supabase Postgres via the Supabase client. Real-time subscriptions keep UI in sync. Billing and AI operations are routed through Supabase Edge Functions to external providers. + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend Components" +participant SL as "Service Layer" +participant ST as "Local Storage" +participant SB as "Supabase Client" +participant EF as "Edge Functions" +participant EXT as "External Providers" +U->>FE : "Interact with UI" +FE->>SL : "Call service methods" +SL->>ST : "Persist locally" +SL->>SB : "Sync to cloud" +SB-->>SL : "Realtime updates" +SL->>EF : "Billing/AI requests" +EF->>EXT : "Gateway/AI API calls" +EXT-->>EF : "Responses" +EF-->>SL : "Function results" +SL-->>FE : "UI state updates" +``` + +**Diagram sources** +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Detailed Component Analysis + +### Frontend Shell and Routing +- main.jsx bootstraps the React application and mounts the root component tree. +- App.jsx defines top-level routing and layout composition. +- Layout.jsx provides consistent page chrome and navigation. + +```mermaid +classDiagram +class Main { ++mount() +} +class App { ++routes() +} +class Layout { ++render(children) +} +Main --> App : "initializes" +App --> Layout : "wraps views" +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) + +### State Management Strategy +- store.jsx centralizes application state and exposes reactive bindings to components. +- Components subscribe to relevant slices of state and dispatch actions or call service layer methods to mutate state. +- Local persistence is coordinated by the storage module; sync module reconciles with cloud state. + +```mermaid +flowchart TD +Start(["Component Action"]) --> UpdateStore["Update Local Store"] +UpdateStore --> Persist["Persist to Local Storage"] +Persist --> Sync["Trigger Sync"] +Sync --> Cloud["Write to Supabase"] +Cloud --> Realtime["Subscribe to Changes"] +Realtime --> Reconcile["Reconcile Conflicts"] +Reconcile --> UpdateStore +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +### Service Layer Modules +- supabase.js configures the Supabase client and common database helpers. +- cloud.js wraps function invocations and error handling for server-side operations. +- sync.js implements conflict detection, merge strategies, and realtime subscriptions. +- entitlement.js evaluates feature access based on subscription status. +- billing.js orchestrates checkout and subscription lifecycle. + +```mermaid +classDiagram +class SupabaseClient { ++configure() ++query(table, filters) ++subscribe(table, filters, callback) +} +class CloudService { ++invoke(name, payload) ++handleErrors(response) +} +class SyncEngine { ++localSnapshot() ++pushChanges() ++pullUpdates() ++resolveConflicts() +} +class EntitlementService { ++checkAccess(feature) +} +class BillingService { ++createCheckout() ++handleWebhooks() +} +SupabaseClient <.. SyncEngine : "reads/writes" +CloudService <.. BillingService : "invokes functions" +EntitlementService <.. SupabaseClient : "queries user/subscription" +``` + +**Diagram sources** +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +### Feature Components +- AccountPage.jsx and Settings.jsx manage user account details and app preferences. +- Tracker.jsx and ScanForm.jsx implement scanning workflows and result capture. +- AiAssistant.jsx triggers AI-powered assistance via server-side proxy. +- OffersPage.jsx and ResultView.jsx display outcomes and next actions. + +```mermaid +graph LR +UI_Account["AccountPage.jsx"] --> Store["store.jsx"] +UI_Settings["Settings.jsx"] --> Store +UI_Tracker["Tracker.jsx"] --> Store +UI_Scan["ScanForm.jsx"] --> Store +UI_AI["AiAssistant.jsx"] --> Cloud["cloud.js"] +UI_Offers["OffersPage.jsx"] --> Store +UI_Result["ResultView.jsx"] --> Store +Store --> Sync["sync.js"] +Store --> Storage["storage.js"] +Cloud --> Functions["Supabase Functions"] +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### Authentication Flow +- auth.jsx handles authentication state and guards routes. +- Supabase client manages sessions and tokens. + +```mermaid +sequenceDiagram +participant User as "User" +participant Auth as "auth.jsx" +participant SB as "Supabase Client" +participant FE as "Frontend" +User->>Auth : "Login attempt" +Auth->>SB : "signInWithPassword()" +SB-->>Auth : "Session" +Auth->>FE : "Set authenticated state" +FE->>FE : "Render protected routes" +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Billing and Webhooks +- billing.js initiates checkout flows and subscribes to events. +- create-checkout function prepares payment sessions. +- capture-paypal-order and create-paypal-order orchestrate PayPal order lifecycle. +- cancel-subscription handles cancellation requests. +- paymongo-webhook and paypal-webhook process provider callbacks to update entitlements. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant BL as "billing.js" +participant CF as "create-checkout/index.ts" +participant PG as "PayPal/PayMongo" +participant WH as "Webhook Handlers" +participant ENT as "entitlement.ts" +FE->>BL : "Initiate checkout" +BL->>CF : "Create checkout session" +CF->>PG : "Redirect to payment" +PG-->>WH : "Webhook event" +WH->>ENT : "Update entitlements" +ENT-->>FE : "Feature access updated" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### AI Proxy Integration +- AiAssistant.jsx invokes AI capabilities via ai-proxy function. +- ai-proxy/index.ts forwards prompts to the AI provider and returns structured responses. +- Shared prompt templates reside in prompts.ts. + +```mermaid +sequenceDiagram +participant UI as "AiAssistant.jsx" +participant CL as "cloud.js" +participant AP as "ai-proxy/index.ts" +participant PR as "AI Provider" +UI->>CL : "Request AI response" +CL->>AP : "Invoke ai-proxy" +AP->>PR : "Send prompt" +PR-->>AP : "Response" +AP-->>CL : "Structured output" +CL-->>UI : "Display result" +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompt.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompt.ts](file://supabase/functions/_shared/prompts.ts) + +## Dependency Analysis +The frontend depends on: +- React ecosystem and Vite for build tooling. +- Supabase client for database and realtime. +- Capacitor for mobile packaging. +- PWA assets for offline support. + +Serverless functions depend on: +- Supabase runtime environment. +- External payment gateways and AI APIs. + +```mermaid +graph TB +PKG["package.json"] +VITE["vite.config.js"] +CAP["capacitor.config.ts"] +HTML["index.html"] +MAN["manifest.webmanifest"] +SW["sw.js"] +PKG --> VITE +PKG --> CAP +HTML --> MAN +HTML --> SW +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [index.html](file://index.html) +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [sw.js](file://public/sw.js) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [index.html](file://index.html) +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [sw.js](file://public/sw.js) + +## Performance Considerations +- Prefer lightweight local state updates and batched writes to reduce network overhead. +- Use targeted realtime subscriptions to minimize payload size. +- Cache frequently accessed data locally and invalidate on changes. +- Defer heavy computations off the main thread where possible. +- Optimize images and assets for faster initial load. + +[No sources needed since this section provides general guidance] + +## Security Architecture +- Authentication handled via Supabase with secure session management. +- Authorization enforced at the database level using Row Level Security policies defined in migrations. +- Sensitive operations (billing, AI proxy) executed in serverless functions to protect secrets and enforce business rules. +- Webhooks validated and processed securely to prevent tampering. + +```mermaid +flowchart TD +Auth["Authentication (Supabase)"] --> RLS["Row Level Security Policies"] +RLS --> DB["Database Access"] +Secrets["Secrets & Keys"] --> Functions["Edge Functions"] +Functions --> External["External Providers"] +Webhooks["Webhook Validation"] --> Functions +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Scalability and Deployment Topology +- Frontend deployed via Netlify or Vercel for global CDN distribution. +- Supabase platform provides scalable Postgres, Edge Functions, and realtime infrastructure. +- Capacitor enables packaging the same codebase for mobile platforms. +- PWA service worker improves offline resilience and performance. + +```mermaid +graph TB +subgraph "CDN" +N["Netlify/Vercel"] +end +subgraph "Runtime" +SB["Supabase Platform"] +end +subgraph "Mobile" +CAP["Capacitor Apps"] +end +subgraph "PWA" +SWF["Service Worker"] +end +N --> SB +CAP --> SB +SWF --> N +``` + +**Diagram sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [sw.js](file://public/sw.js) +- [config.toml](file://supabase/config.toml) + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [sw.js](file://public/sw.js) +- [config.toml](file://supabase/config.toml) + +## Troubleshooting Guide +- Authentication issues: + - Verify session state and token validity. + - Check Supabase client configuration and environment variables. +- Sync conflicts: + - Inspect local snapshot vs cloud state. + - Review conflict resolution logic and timestamps. +- Billing failures: + - Validate webhook signatures and payloads. + - Confirm function logs for gateway errors. +- AI proxy errors: + - Ensure prompt formatting and provider credentials. + - Monitor function latency and rate limits. + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [billing.js](file://src/lib/billing.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Conclusion +ApplyGuard PH employs a clean separation between UI components and service-layer modules, leveraging Supabase for data persistence, realtime updates, and serverless functions. The architecture supports scalability through CDN-hosted frontends and managed backend services, while maintaining security via RLS and function-bound secrets. The data flow ensures reliable local-first operation with robust cloud synchronization and real-time consistency. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Authentication & User Management/Authentication & User Management.md b/.qoder/repowiki/en/content/Authentication & User Management/Authentication & User Management.md new file mode 100644 index 0000000..c24935d --- /dev/null +++ b/.qoder/repowiki/en/content/Authentication & User Management/Authentication & User Management.md @@ -0,0 +1,453 @@ +# Authentication & User Management + + +**Referenced Files in This Document** +- [src/auth.jsx](file://src/auth.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/store.jsx](file://src/store.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/config.toml](file://supabase/config.toml) +- [package.json](file://package.json) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains how ApplyGuard PH handles authentication, user sessions, and account lifecycle using Supabase. It also documents the entitlement system for premium features, subscription status tracking, access control mechanisms, user profile data structure, preferences management, and account settings. Security considerations, password policies, and data privacy measures are included, along with the relationship between authentication state and feature access. + +## Project Structure +The authentication and user management logic spans client-side React code, Supabase client configuration, serverless functions for billing and entitlements, and database migrations that define schema and subscription fulfillment. + +```mermaid +graph TB +subgraph "Frontend (React)" +A["src/auth.jsx"] +B["src/store.jsx"] +C["src/components/AccountPage.jsx"] +D["src/components/Settings.jsx"] +end +subgraph "Client Lib" +E["src/lib/supabase.js"] +F["src/lib/entitlement.js"] +end +subgraph "Supabase Edge Functions" +G["_shared/entitlement.ts"] +H["paymongo-webhook/index.ts"] +I["paypal-webhook/index.ts"] +J["cancel-subscription/index.ts"] +K["create-checkout/index.ts"] +L["capture-paypal-order/index.ts"] +M["create-paypal-order/index.ts"] +N["_shared/http.ts"] +O["_shared/paypal.ts"] +P["_shared/paypal-runtime.ts"] +end +subgraph "Database" +Q["migrations/001_schema.sql"] +R["migrations/002_paypal_fulfillment.sql"] +end +A --> E +A --> F +B --> E +C --> F +D --> E +F --> G +H --> G +I --> G +J --> G +K --> G +L --> G +M --> G +G --> Q +G --> R +``` + +**Diagram sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) +- [supabase/functions/paymongo-webhook/index.ts:1-200](file://supabase/functions/paymongo-webhook/index.ts#L1-L200) +- [supabase/functions/paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) +- [supabase/functions/cancel-subscription/index.ts:1-200](file://supabase/functions/cancel-subscription/index.ts#L1-L200) +- [supabase/functions/create-checkout/index.ts:1-200](file://supabase/functions/create-checkout/index.ts#L1-L200) +- [supabase/functions/capture-paypal-order/index.ts:1-200](file://supabase/functions/capture-paypal-order/index.ts#L1-L200) +- [supabase/functions/create-paypal-order/index.ts:1-200](file://supabase/functions/create-paypal-order/index.ts#L1-L200) +- [supabase/functions/_shared/http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) +- [supabase/functions/_shared/paypal.ts:1-200](file://supabase/functions/_shared/paypal.ts#L1-L200) +- [supabase/functions/_shared/paypal-runtime.ts:1-200](file://supabase/functions/_shared/paypal-runtime.ts#L1-L200) + +**Section sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +## Core Components +- Authentication entry point and session handling: + - The auth module initializes the Supabase client, manages sign-in/sign-out flows, and exposes current session and user state to the app. + - It integrates with global store to keep UI in sync with auth state changes. +- Supabase client configuration: + - Centralized client setup with environment-based configuration and default options. +- Entitlements and access control: + - Client-side entitlement checks call a shared serverless function to determine premium feature access based on subscription status. +- Account and Settings pages: + - Provide UI for viewing/updating profile data and managing preferences. + +Key responsibilities: +- Maintain authenticated session across navigation and refreshes. +- Enforce feature gating based on entitlements. +- Persist minimal user preferences locally while syncing critical settings via Supabase. + +**Section sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/store.jsx:1-200](file://src/store.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [src/components/AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [src/components/Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) + +## Architecture Overview +Authentication and entitlements flow: +- Frontend uses Supabase client to authenticate users and maintain sessions. +- Feature access is determined by calling a serverless entitlement function that reads subscription state from the database. +- Billing webhooks update subscription records; serverless functions reconcile payments and grant or revoke access accordingly. + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend (auth.jsx)" +participant SB as "Supabase Auth" +participant ENT as "Entitlement Function (_shared/entitlement.ts)" +participant DB as "Supabase Database" +participant PM as "PayMongo/PayPal Webhooks" +U->>FE : "Sign In / Sign Up" +FE->>SB : "authenticate(credentials)" +SB-->>FE : "session + user" +FE->>ENT : "checkEntitlements(userId)" +ENT->>DB : "read subscriptions & plans" +DB-->>ENT : "subscription status" +ENT-->>FE : "entitlements result" +FE-->>U : "grant/deny premium features" +PM->>ENT : "webhook event" +ENT->>DB : "update subscription record" +DB-->>ENT : "acknowledged" +ENT-->>PM : "success response" +``` + +**Diagram sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/functions/paymongo-webhook/index.ts:1-200](file://supabase/functions/paymongo-webhook/index.ts#L1-L200) +- [supabase/functions/paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +## Detailed Component Analysis + +### Authentication and Session Management +- Initialization: + - The auth module sets up the Supabase client and listens for auth state changes to keep the application synchronized. +- Sign-in/Sign-up: + - Supports email/password and provider-based flows through Supabase Auth. +- Session persistence: + - Relies on Supabase’s built-in session storage and auto-refresh behavior. +- Global integration: + - Exposes current user/session to the app via a centralized store. + +```mermaid +flowchart TD +Start(["App Start"]) --> Init["Initialize Supabase Client"] +Init --> Listen["Listen to Auth State Changes"] +Listen --> HasSession{"Has Active Session?"} +HasSession --> |Yes| LoadProfile["Load User Profile"] +HasSession --> |No| ShowLogin["Show Login Screen"] +LoadProfile --> CheckEntitlements["Check Entitlements"] +CheckEntitlements --> GrantAccess["Grant Premium Access if Eligible"] +GrantAccess --> End(["Ready"]) +ShowLogin --> End +``` + +**Diagram sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/store.jsx:1-200](file://src/store.jsx#L1-L200) + +**Section sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/store.jsx:1-200](file://src/store.jsx#L1-L200) + +### Entitlement System and Access Control +- Client-side checks: + - The entitlement library calls a serverless function to evaluate whether a user has premium access. +- Server-side evaluation: + - The shared entitlement function queries subscription records and plan details to compute entitlements. +- Subscription updates: + - Payment webhooks trigger entitlement updates via serverless functions. + +```mermaid +classDiagram +class EntitlementClient { ++checkEntitlements(userId) Promise~boolean~ +} +class EntitlementServer { ++evaluate(userId) boolean ++reconcile(webhookEvent) void +} +class SubscriptionStore { ++getSubscription(userId) Record ++updateStatus(userId, status) void +} +EntitlementClient --> EntitlementServer : "HTTP call" +EntitlementServer --> SubscriptionStore : "reads/writes" +``` + +**Diagram sources** +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +**Section sources** +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +### Billing Integration and Subscription Lifecycle +- Checkout creation: + - Serverless endpoints create checkout sessions for PayMongo and PayPal. +- Order capture: + - PayPal order capture endpoint finalizes payment and updates subscription status. +- Webhook processing: + - PayMongo and PayPal webhook handlers update subscription records and reconcile entitlements. +- Cancellation: + - Cancel subscription endpoint revokes access and updates records. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant CC as "create-checkout/index.ts" +participant PMW as "paymongo-webhook/index.ts" +participant PPW as "paypal-webhook/index.ts" +participant PCO as "capture-paypal-order/index.ts" +participant CS as "cancel-subscription/index.ts" +participant ENT as "_shared/entitlement.ts" +participant DB as "Database" +FE->>CC : "Create checkout session" +CC-->>FE : "checkout URL" +PMW->>ENT : "Payment success webhook" +ENT->>DB : "Update subscription status" +PPW->>ENT : "Payment success webhook" +ENT->>DB : "Update subscription status" +PCO->>ENT : "Capture order" +ENT->>DB : "Finalize subscription" +CS->>ENT : "Cancel subscription" +ENT->>DB : "Revoke access" +``` + +**Diagram sources** +- [supabase/functions/create-checkout/index.ts:1-200](file://supabase/functions/create-checkout/index.ts#L1-L200) +- [supabase/functions/paymongo-webhook/index.ts:1-200](file://supabase/functions/paymongo-webhook/index.ts#L1-L200) +- [supabase/functions/paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) +- [supabase/functions/capture-paypal-order/index.ts:1-200](file://supabase/functions/capture-paypal-order/index.ts#L1-L200) +- [supabase/functions/cancel-subscription/index.ts:1-200](file://supabase/functions/cancel-subscription/index.ts#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +**Section sources** +- [supabase/functions/create-checkout/index.ts:1-200](file://supabase/functions/create-checkout/index.ts#L1-L200) +- [supabase/functions/paymongo-webhook/index.ts:1-200](file://supabase/functions/paymongo-webhook/index.ts#L1-L200) +- [supabase/functions/paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) +- [supabase/functions/capture-paypal-order/index.ts:1-200](file://supabase/functions/capture-paypal-order/index.ts#L1-L200) +- [supabase/functions/cancel-subscription/index.ts:1-200](file://supabase/functions/cancel-subscription/index.ts#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +### User Profile Data Structure and Preferences +- Profile fields: + - Basic identity and contact information stored in user profiles. +- Preferences: + - Local storage for non-critical preferences; critical settings synced via Supabase. +- Account page: + - Displays and allows editing of profile data. +- Settings page: + - Manages user preferences and account-related toggles. + +```mermaid +erDiagram +USER { +uuid id PK +string email UK +string full_name +timestamp created_at +timestamp updated_at +} +PROFILE { +uuid user_id PK FK +string avatar_url +jsonb preferences +boolean premium_active +timestamp last_subscription_check +} +SUBSCRIPTION { +uuid id PK +uuid user_id FK +enum provider +string external_id +enum status +timestamp starts_at +timestamp ends_at +timestamp created_at +timestamp updated_at +} +USER ||--o{ PROFILE : "has one" +USER ||--o{ SUBSCRIPTION : "owns" +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) +- [src/components/AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [src/components/Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) + +**Section sources** +- [src/components/AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [src/components/Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +### Security Considerations, Password Policies, and Data Privacy +- Authentication security: + - Leverages Supabase Auth for secure credential handling, token management, and session persistence. +- Password policies: + - Follow Supabase’s default password requirements and best practices; enforce strong passwords at signup. +- Data privacy: + - Minimize sensitive data in local storage; prefer server-side validation and authorization. +- Access control: + - Use Row Level Security (RLS) policies in Supabase to restrict data access per user. +- Secrets management: + - Store API keys and secrets in environment variables configured via Supabase project settings. + +**Section sources** +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [supabase/config.toml:1-200](file://supabase/config.toml#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) + +## Dependency Analysis +The following diagram shows key dependencies among authentication, entitlements, billing, and database layers. + +```mermaid +graph LR +Auth["src/auth.jsx"] --> Supabase["src/lib/supabase.js"] +Auth --> Store["src/store.jsx"] +EntClient["src/lib/entitlement.js"] --> EntServer["supabase/functions/_shared/entitlement.ts"] +EntServer --> Schema["supabase/migrations/001_schema.sql"] +EntServer --> Fulfillment["supabase/migrations/002_paypal_fulfillment.sql"] +PayMongo["supabase/functions/paymongo-webhook/index.ts"] --> EntServer +PayPalWebhook["supabase/functions/paypal-webhook/index.ts"] --> EntServer +CapturePP["supabase/functions/capture-paypal-order/index.ts"] --> EntServer +CreateCheckout["supabase/functions/create-checkout/index.ts"] --> EntServer +CancelSub["supabase/functions/cancel-subscription/index.ts"] --> EntServer +HTTP["supabase/functions/_shared/http.ts"] --> EntServer +PayPalLib["supabase/functions/_shared/paypal.ts"] --> EntServer +PayPalRuntime["supabase/functions/_shared/paypal-runtime.ts"] --> EntServer +``` + +**Diagram sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [src/store.jsx:1-200](file://src/store.jsx#L1-L200) +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/_shared/entitlement.ts:1-200](file://supabase/functions/_shared/entitlement.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) +- [supabase/functions/paymongo-webhook/index.ts:1-200](file://supabase/functions/paymongo-webhook/index.ts#L1-L200) +- [supabase/functions/paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) +- [supabase/functions/capture-paypal-order/index.ts:1-200](file://supabase/functions/capture-paypal-order/index.ts#L1-L200) +- [supabase/functions/create-checkout/index.ts:1-200](file://supabase/functions/create-checkout/index.ts#L1-L200) +- [supabase/functions/cancel-subscription/index.ts:1-200](file://supabase/functions/cancel-subscription/index.ts#L1-L200) +- [supabase/functions/_shared/http.ts:1-200](file://supabase/functions/_shared/http.ts#L1-L200) +- [supabase/functions/_shared/paypal.ts:1-200](file://supabase/functions/_shared/paypal.ts#L1-L200) +- [supabase/functions/_shared/paypal-runtime.ts:1-200](file://supabase/functions/_shared/paypal-runtime.ts#L1-L200) + +**Section sources** +- [package.json:1-200](file://package.json#L1-L200) + +## Performance Considerations +- Cache entitlement results briefly on the client to reduce repeated server calls during a session. +- Debounce frequent preference updates; batch writes where possible. +- Use Supabase Realtime to reactively update UI when subscription status changes. +- Avoid heavy computations in UI threads; offload to serverless functions when necessary. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: + - Verify Supabase project credentials and network connectivity. + - Check browser console for error messages related to session initialization. +- Entitlement mismatches: + - Confirm subscription records exist and are up-to-date after payment events. + - Inspect webhook logs for successful processing and reconciliation steps. +- Billing webhook errors: + - Validate payload signatures and ensure idempotent processing. + - Review error responses and retry strategies in webhook handlers. +- Profile and settings sync: + - Ensure RLS policies allow read/write access for the current user. + - Confirm local storage does not conflict with server-synced preferences. + +**Section sources** +- [src/auth.jsx:1-200](file://src/auth.jsx#L1-L200) +- [src/lib/entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [supabase/functions/paymongo-webhook/index.ts:1-200](file://supabase/functions/paymongo-webhook/index.ts#L1-L200) +- [supabase/functions/paypal-webhook/index.ts:1-200](file://supabase/functions/paypal-webhook/index.ts#L1-L200) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) + +## Conclusion +ApplyGuard PH integrates Supabase Auth for secure authentication and session management, with a robust entitlement system backed by serverless functions and database-driven subscription records. The architecture ensures consistent access control, reliable billing reconciliation, and a clear separation of concerns between client and server components. Following the security and privacy recommendations will help maintain a safe and compliant user experience. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices +- Environment configuration: + - Refer to Supabase config and project settings for secrets and runtime options. +- Package dependencies: + - Review package.json for relevant libraries used in authentication and billing integrations. + +**Section sources** +- [supabase/config.toml:1-200](file://supabase/config.toml#L1-L200) +- [package.json:1-200](file://package.json#L1-L200) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Authentication & User Management/Authentication System.md b/.qoder/repowiki/en/content/Authentication & User Management/Authentication System.md new file mode 100644 index 0000000..71c5cca --- /dev/null +++ b/.qoder/repowiki/en/content/Authentication & User Management/Authentication System.md @@ -0,0 +1,421 @@ +# Authentication System + + +**Referenced Files in This Document** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [config.toml](file://supabase/config.toml) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction + +ApplyGuard PH is a comprehensive application built with React and Supabase that implements a robust authentication system. The authentication system leverages Supabase's built-in authentication capabilities to provide secure user registration, login/logout flows, session management, and protected route access. This document provides comprehensive documentation of the authentication architecture, implementation details, security measures, and best practices for maintaining secure user sessions. + +The authentication system follows modern React patterns using context providers, custom hooks, and component-based architecture to ensure maintainable and scalable user authentication across the application. + +## Project Structure + +The authentication system is distributed across several key files and directories: + +```mermaid +graph TB +subgraph "Frontend Application" +Main[main.jsx] --> App[App.jsx] +App --> AuthContext[auth.jsx] +App --> Store[store.jsx] +App --> Layout[Layout.jsx] +subgraph "Components" +AccountPage[AccountPage.jsx] +ProtectedRoutes[Protected Routes] +end +AuthContext --> AccountPage +Store --> AccountPage +end +subgraph "Authentication Layer" +SupabaseClient[supabase.js] +SupabaseAuth[Supabase Auth] +end +subgraph "Backend Services" +SupabaseDB[(Supabase Database)] +SupabaseStorage[(Supabase Storage)] +end +Main --> SupabaseClient +AuthContext --> SupabaseClient +SupabaseClient --> SupabaseAuth +SupabaseAuth --> SupabaseDB +SupabaseAuth --> SupabaseStorage +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Core Components + +### Authentication Context Provider + +The authentication system centers around a context provider that manages user state, authentication methods, and session lifecycle. This component serves as the single source of truth for authentication state throughout the application. + +Key responsibilities include: +- User state management and persistence +- Authentication method implementations (login, logout, register) +- Session monitoring and automatic refresh +- Error handling and user feedback +- Loading state management + +### Supabase Client Configuration + +The Supabase client is configured with proper authentication settings, including: +- Environment-specific configuration +- Real-time subscription setup +- Error handling middleware +- Token refresh mechanisms + +### Protected Route Implementation + +Protected routes are implemented using higher-order components or route guards that check authentication status before rendering protected content. These components handle: +- Authentication status verification +- Redirect logic for unauthenticated users +- Loading states during authentication checks +- Role-based access control (if implemented) + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview + +The authentication architecture follows a layered approach with clear separation of concerns: + +```mermaid +sequenceDiagram +participant User as User Interface +participant AuthProvider as Auth Context Provider +participant SupabaseClient as Supabase Client +participant SupabaseAuth as Supabase Auth Service +participant Database as Supabase Database +User->>AuthProvider : Login Request +AuthProvider->>SupabaseClient : signIn(credentials) +SupabaseClient->>SupabaseAuth : authenticate() +SupabaseAuth->>Database : validate credentials +Database-->>SupabaseAuth : user data + tokens +SupabaseAuth-->>SupabaseClient : auth session +SupabaseClient-->>AuthProvider : authenticated session +AuthProvider->>AuthProvider : update local state +AuthProvider-->>User : redirect to dashboard +Note over User,Database : Session Management +SupabaseAuth->>SupabaseAuth : monitor session changes +SupabaseAuth->>SupabaseAuth : auto-refresh tokens +SupabaseAuth->>SupabaseAuth : handle session expiration +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Data Flow Architecture + +```mermaid +flowchart TD +Start([Application Start]) --> InitSupabase["Initialize Supabase Client"] +InitSupabase --> CheckSession["Check Existing Session"] +CheckSession --> HasSession{"Session Exists?"} +HasSession --> |Yes| LoadUserData["Load User Data"] +HasSession --> |No| ShowLogin["Show Login Screen"] +LoadUserData --> UpdateState["Update Auth State"] +UpdateState --> RenderApp["Render Protected Content"] +ShowLogin --> UserAction{"User Action"} +UserAction --> |Login| HandleLogin["Handle Login"] +UserAction --> |Register| HandleRegister["Handle Registration"] +HandleLogin --> ValidateCredentials["Validate Credentials"] +HandleRegister --> CreateAccount["Create Account"] +ValidateCredentials --> Success{"Authentication Success?"} +CreateAccount --> Success +Success --> |Yes| UpdateSession["Update Session"] +Success --> |No| ShowError["Display Error Message"] +UpdateSession --> UpdateState +ShowError --> ShowLogin +RenderApp --> MonitorSession["Monitor Session Changes"] +MonitorSession --> SessionExpired{"Session Expired?"} +SessionExpired --> |Yes| ClearSession["Clear Session"] +SessionExpired --> |No| ContinueApp["Continue Application"] +ClearSession --> ShowLogin +ContinueApp --> RenderApp +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Authentication Context Implementation + +The authentication context provides a comprehensive API for managing user authentication throughout the application lifecycle. + +#### Key Methods and Properties + +The context exposes essential authentication methods including user registration, login/logout functionality, and session management. It maintains reactive state that automatically updates UI components when authentication status changes. + +#### State Persistence Strategy + +Authentication state persists across browser sessions using Supabase's built-in session storage mechanisms. The implementation handles: +- Automatic session restoration on app reload +- Cross-tab synchronization +- Secure token storage +- Session expiration handling + +#### Error Handling Patterns + +Comprehensive error handling covers network failures, invalid credentials, server errors, and edge cases. Errors are normalized and presented to users through consistent feedback mechanisms. + +**Section sources** +- [auth.jsx](file://src/auth.jsx) + +### Supabase Integration Layer + +The Supabase integration layer abstracts database operations and authentication calls behind a clean interface. + +#### Client Configuration + +The client is configured with environment-specific settings, connection pooling, and retry logic for resilience. + +#### Authentication Methods + +Authentication methods wrap Supabase's native functions with additional error handling, loading states, and user feedback. + +#### Real-time Features + +Real-time subscriptions enable live updates for user profile changes and other dynamic content. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) + +### Protected Route Components + +Protected routes ensure that only authenticated users can access sensitive application features. + +#### Route Guard Implementation + +Route guards check authentication status before rendering protected components, redirecting unauthenticated users to appropriate login pages. + +#### Loading States + +Loading states prevent flash of unauthenticated content during authentication checks. + +#### Role-Based Access Control + +Extended protection includes role-based access control for different user types and permission levels. + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) + +### User State Management + +The application uses a combination of React context and local storage to manage user state efficiently. + +#### State Synchronization + +User state synchronizes between context, local storage, and Supabase backend to ensure consistency across tabs and sessions. + +#### Performance Optimizations + +State updates are optimized to minimize re-renders while maintaining responsive user interfaces. + +**Section sources** +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis + +The authentication system has well-defined dependencies and clear separation of concerns: + +```mermaid +graph LR +subgraph "UI Layer" +App[App.jsx] +Layout[Layout.jsx] +AccountPage[AccountPage.jsx] +end +subgraph "Business Logic" +AuthContext[auth.jsx] +Store[store.jsx] +end +subgraph "Data Layer" +SupabaseClient[supabase.js] +SupabaseService[Supabase Auth] +end +subgraph "External Dependencies" +SupabaseDB[(Supabase DB)] +LocalStorage[Browser Storage] +end +App --> AuthContext +Layout --> AuthContext +AccountPage --> AuthContext +AuthContext --> SupabaseClient +Store --> AuthContext +SupabaseClient --> SupabaseService +SupabaseService --> SupabaseDB +AuthContext --> LocalStorage +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Component Coupling Analysis + +The authentication system demonstrates low coupling between components while maintaining high cohesion within the authentication domain. Each component has a single responsibility and communicates through well-defined interfaces. + +### External Dependencies + +The system relies on Supabase for authentication, database operations, and real-time features. Browser APIs provide local storage and session management capabilities. + +**Section sources** +- [app.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Performance Considerations + +### Authentication State Optimization + +The authentication system optimizes performance through: +- Memoized authentication checks +- Debounced state updates +- Lazy loading of protected routes +- Efficient re-rendering strategies + +### Network Request Optimization + +Network requests are optimized with: +- Request deduplication +- Caching strategies for user data +- Retry logic for failed requests +- Connection pooling through Supabase client + +### Memory Management + +Memory usage is minimized through: +- Proper cleanup of event listeners +- Garbage collection of unused authentication data +- Efficient session storage usage + +## Troubleshooting Guide + +### Common Authentication Issues + +#### Session Not Persisting +- Verify Supabase client configuration +- Check browser storage permissions +- Ensure proper environment variables + +#### Authentication Loop +- Review redirect logic in protected routes +- Check for infinite loading states +- Validate session checking logic + +#### Token Refresh Failures +- Monitor network connectivity +- Check Supabase service status +- Implement fallback authentication methods + +### Debugging Techniques + +#### Console Logging +Enable detailed logging during development to track authentication flow and identify issues. + +#### Network Inspection +Use browser developer tools to inspect authentication requests and responses. + +#### State Inspection +Monitor authentication state changes and verify expected behavior. + +### Error Recovery Strategies + +Implement graceful degradation when authentication services are unavailable: +- Offline mode support +- Cached session validation +- User-friendly error messages + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion + +The ApplyGuard PH authentication system provides a robust, secure, and user-friendly authentication experience built on Supabase's enterprise-grade infrastructure. The modular architecture ensures maintainability and scalability while providing comprehensive error handling and performance optimizations. + +Key strengths of the implementation include: +- Clean separation of concerns +- Comprehensive error handling +- Performance optimizations +- Security best practices +- Extensible architecture for future enhancements + +The system is designed to scale with application growth while maintaining security and performance standards. + +## Appendices + +### Security Best Practices + +#### Token Management +- Use HTTPS for all authentication requests +- Implement proper token expiration handling +- Store tokens securely using Supabase's built-in mechanisms +- Avoid storing sensitive data in localStorage + +#### Session Security +- Implement session timeout policies +- Use secure cookie attributes where applicable +- Validate sessions on each request +- Monitor for suspicious authentication patterns + +#### Input Validation +- Sanitize all user inputs +- Validate email formats and password strength +- Implement rate limiting for authentication attempts +- Use CSRF protection for form submissions + +### Configuration Reference + +#### Environment Variables +Required environment variables for Supabase integration: +- Supabase URL +- Supabase anonymous key +- Development/production flags + +#### Database Schema +Authentication-related database tables and relationships are defined in the migration files. + +**Section sources** +- [config.toml](file://supabase/config.toml) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Authentication & User Management/Entitlements & Access Control.md b/.qoder/repowiki/en/content/Authentication & User Management/Entitlements & Access Control.md new file mode 100644 index 0000000..995b33a --- /dev/null +++ b/.qoder/repowiki/en/content/Authentication & User Management/Entitlements & Access Control.md @@ -0,0 +1,430 @@ +# Entitlements & Access Control + + +**Referenced Files in This Document** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [billing.js](file://src/lib/billing.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the entitlements and access control system for ApplyGuard PH. It covers how premium features are gated by subscription status, how entitlements are evaluated on the client and server, how billing events update feature access, and how to implement protected features with robust error handling and fallback behaviors. The goal is to provide a clear mental model and practical guidance for developers implementing or extending access controls. + +## Project Structure +The entitlements system spans both client-side logic and serverless functions: +- Client-side entitlement evaluation and UI gating live in the frontend library and React store. +- Server-side entitlement computation and billing integrations live in Supabase Edge Functions and shared utilities. +- Documentation for monetization architecture and PayMongo subscriptions provides additional context. + +```mermaid +graph TB +subgraph "Client" +A["src/lib/entitlement.js"] +B["src/lib/billing.js"] +C["src/store.jsx"] +D["src/auth.jsx"] +E["src/lib/supabase.js"] +end +subgraph "Server (Supabase Functions)" +F["supabase/functions/_shared/entitlement.ts"] +G["supabase/functions/_shared/http.ts"] +H["supabase/functions/create-checkout/index.ts"] +I["supabase/functions/paymongo-webhook/index.ts"] +J["supabase/functions/paypal-webhook/index.ts"] +end +A --> C +B --> C +D --> C +C --> E +A --> F +F --> G +H --> I +H --> J +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [billing.js](file://src/lib/billing.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Client entitlement evaluator: centralizes feature flags, permission checks, and caching strategies. +- Billing integration: manages checkout flows and listens to webhook-driven state changes. +- Server entitlement service: authoritative source of truth for entitlements based on subscription lifecycle and payment provider webhooks. +- Store and auth integration: exposes current user’s entitlements to components and triggers refreshes when authentication or billing state changes. + +Key responsibilities: +- Evaluate whether a user can access a given feature. +- Cache results locally for resilience and performance. +- Refresh entitlements after successful payments or subscription updates. +- Provide safe defaults and graceful degradation under network failures. + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [billing.js](file://src/lib/billing.js) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview +The entitlements architecture follows a client-server model with an authoritative server and a resilient client cache. + +```mermaid +sequenceDiagram +participant UI as "React UI" +participant Store as "Store (store.jsx)" +participant Auth as "Auth (auth.jsx)" +participant Ent as "Entitlement Client (entitlement.js)" +participant Srv as "Entitlement Server (entitlement.ts)" +participant Webhook as "PayMongo/PayPal Webhooks" +participant Checkout as "Create Checkout (create-checkout/index.ts)" +UI->>Store : Request feature access +Store->>Ent : Check entitlement(feature) +alt Cached result available +Ent-->>Store : {allowed, reason} +else No cache or stale +Ent->>Srv : Compute entitlement(user, feature) +Srv-->>Ent : {allowed, reason} +Ent->>Ent : Persist cache +Ent-->>Store : {allowed, reason} +end +Store-->>UI : Render gated feature or prompt upgrade +Note over Checkout,Webhook : Payment flow +UI->>Checkout : Start checkout +Checkout->>Webhook : Provider notifies success +Webhook->>Srv : Update subscription state +Srv-->>Ent : New entitlements available +Ent->>Ent : Invalidate cache +Ent->>Srv : Re-fetch latest entitlements +Ent-->>Store : Updated {allowed, reason} +Store-->>UI : Unlock premium feature +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Detailed Component Analysis + +### Client Entitlement Service +Responsibilities: +- Feature flag registry and permission matrix. +- Local caching with TTL and invalidation hooks. +- Network request orchestration to server entitlements. +- Safe defaults and offline behavior. + +Typical usage pattern: +- Call a check function with a feature identifier. +- Receive a decision object indicating allowed/denied and a reason. +- Use the decision to gate UI and business logic. + +```mermaid +flowchart TD +Start(["Check Entitlement"]) --> HasCache{"Cache valid?"} +HasCache --> |Yes| ReturnCache["Return cached decision"] +HasCache --> |No| Fetch["Call server entitlements"] +Fetch --> Success{"Network ok?"} +Success --> |Yes| Persist["Persist to cache"] +Persist --> ReturnResult["Return decision"] +Success --> |No| Fallback["Use offline policy
and/or deny-by-default"] +Fallback --> ReturnFallback["Return fallback decision"] +ReturnCache --> End(["Done"]) +ReturnResult --> End +ReturnFallback --> End +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) + +### Server Entitlement Service +Responsibilities: +- Authoritative computation of entitlements from subscription state. +- Integration with payment providers via webhooks. +- Deterministic rules for trial, active, expired, and canceled states. +- Consistent API for clients to query entitlements. + +Integration points: +- HTTP helpers for outbound calls and response normalization. +- Webhook handlers that update subscription records and invalidate caches. + +```mermaid +classDiagram +class EntitlementService { ++compute(user, feature) Decision ++invalidate(user) void ++getSubscriptionState(user) SubscriptionState +} +class HttpHelpers { ++request(url, options) Response ++normalizeError(error) Error +} +class WebhookHandlers { ++handlePayMongo(payload) void ++handlePayPal(payload) void +} +EntitlementService --> HttpHelpers : "uses" +WebhookHandlers --> EntitlementService : "updates state" +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Billing Integration and Checkout Flow +Responsibilities: +- Initiate checkout sessions. +- Listen to provider webhooks to reconcile subscription state. +- Trigger client-side cache invalidation upon successful fulfillment. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "UI" +participant Checkout as "Create Checkout" +participant Provider as "Payment Provider" +participant Webhook as "Webhook Handler" +participant Ent as "Entitlement Service" +participant Client as "Client Entitlement" +User->>UI : Click "Upgrade" +UI->>Checkout : Create checkout session +Checkout->>Provider : Redirect to payment +Provider-->>Webhook : Notify success/failure +Webhook->>Ent : Update subscription state +Ent-->>Client : Invalidate cache +Client->>Ent : Re-fetch entitlements +Ent-->>Client : New decision +Client-->>UI : Unlock premium feature +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +### Store and Auth Integration +Responsibilities: +- Expose current user’s entitlements to components. +- Refresh entitlements on sign-in/sign-out and billing events. +- Coordinate caching and revalidation. + +```mermaid +sequenceDiagram +participant Auth as "Auth (auth.jsx)" +participant Store as "Store (store.jsx)" +participant Ent as "Entitlement Client (entitlement.js)" +participant Srv as "Entitlement Server (entitlement.ts)" +Auth->>Store : User signed in/out +Store->>Ent : Reset/refresh entitlements +Ent->>Srv : Fetch latest entitlements +Srv-->>Ent : Decision set +Ent-->>Store : Update global state +Store-->>Components : Re-render with new access +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Dependency Analysis +- Client dependencies: + - Entitlement client depends on local storage/cache and the server entitlement endpoint. + - Store depends on auth state and entitlement client to keep UI consistent. +- Server dependencies: + - Entitlement service depends on HTTP helpers and subscription data updated by webhooks. + - Webhook handlers depend on payment provider payloads and call into the entitlement service to reconcile state. + +```mermaid +graph LR +EntClient["entitlement.js"] --> EntServer["entitlement.ts"] +EntClient --> Store["store.jsx"] +Store --> Auth["auth.jsx"] +EntServer --> Http["http.ts"] +WebhookPM["paymongo-webhook/index.ts"] --> EntServer +WebhookPP["paypal-webhook/index.ts"] --> EntServer +Checkout["create-checkout/index.ts"] --> WebhookPM +Checkout --> WebhookPP +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +## Performance Considerations +- Cache aggressively on the client with reasonable TTLs to reduce server load and improve responsiveness. +- Invalidate cache promptly on known events (sign-in, checkout completion, webhook processing). +- Batch feature checks where possible to minimize redundant requests. +- Prefer deterministic server-side decisions to avoid drift between client and server. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Network failures during entitlement checks: + - Ensure the client falls back to a safe default (deny-by-default for premium features) and retries with exponential backoff. + - Verify cache invalidation does not leave stale entries after transient errors. +- Subscription changes not reflected immediately: + - Confirm webhooks are processed successfully and trigger cache invalidation. + - Add explicit re-fetch hooks after checkout completion. +- Offline access policies: + - Define clear offline behavior for each feature (e.g., allow read-only, deny write operations). + - Log offline denials to aid diagnostics. +- Inconsistent entitlements across devices: + - Ensure server is the single source of truth; client should always re-validate after reconnecting. + +Operational tips: +- Instrument logs around cache hits/misses, network errors, and webhook processing outcomes. +- Add tests for edge cases such as expired trials, canceled subscriptions, and partial webhook deliveries. + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Conclusion +ApplyGuard PH implements a robust entitlements system that gates premium features based on verified subscription status. The design emphasizes a server-authoritative model with a resilient client cache, timely invalidation on billing events, and clear fallback behaviors for offline or error conditions. By following the patterns outlined here, teams can safely add new premium features, customize entitlement checks, and maintain a consistent user experience across all environments. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Implementing Protected Features +- Register a new feature flag in the client entitlement registry. +- Wrap feature entry points with an entitlement check and render appropriate UI (locked vs unlocked). +- On denial, present a clear upgrade path or explain limitations. + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [store.jsx](file://src/store.jsx) + +### Custom Entitlement Checks +- Extend the server entitlement service to incorporate custom rules (e.g., admin overrides, beta access). +- Keep client checks thin and delegate complex logic to the server. +- Validate inputs and return structured decisions with reasons for transparency. + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Handling Access Denied Scenarios +- Show contextual messaging explaining why access is denied. +- Offer retry mechanisms if the denial may be due to transient issues. +- Track analytics to understand denial patterns and improve UX. + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) + +### Real-Time Updates and Fallback Behaviors +- Subscribe to auth and billing events to trigger immediate re-evaluation. +- Use optimistic UI only when safe; otherwise, wait for server confirmation. +- Define explicit offline policies per feature to balance usability and security. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [entitlement.js](file://src/lib/entitlement.js) + +### Relationship Between Billing Status and Feature Access +- Active subscriptions unlock premium features. +- Trials follow predefined limits and expiration rules. +- Canceled or expired subscriptions revert to free-tier access. + +For detailed provider-specific flows, see: + +**Section sources** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Authentication & User Management/User Accounts & Profiles.md b/.qoder/repowiki/en/content/Authentication & User Management/User Accounts & Profiles.md new file mode 100644 index 0000000..8c85d9f --- /dev/null +++ b/.qoder/repowiki/en/content/Authentication & User Management/User Accounts & Profiles.md @@ -0,0 +1,469 @@ +# User Accounts & Profiles + + +**Referenced Files in This Document** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [csv.js](file://src/lib/csv.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains user account and profile management for ApplyGuard PH, focusing on the AccountPage component, profile data structure, settings and preferences, local storage strategies, cloud synchronization, and data consistency across devices. It also covers privacy considerations, data retention policies, and GDPR-related features such as export and deletion. + +## Project Structure +The user account and profile functionality spans UI components, state management, persistence, and cloud services: +- UI: AccountPage component renders profile editing, export/import, and account deletion flows. +- State: Global store exposes current user and profile state to the app. +- Persistence: Local storage utilities manage offline preferences and cached data. +- Cloud: Supabase client, cloud helpers, and sync engine handle remote profiles and cross-device consistency. +- Billing/Entitlements: Integration with billing providers and entitlement checks affects feature access tied to accounts. + +```mermaid +graph TB +subgraph "UI" +AP["AccountPage.jsx"] +end +subgraph "State" +ST["store.jsx"] +end +subgraph "Persistence" +LS["storage.js"] +end +subgraph "Cloud" +SB["supabase.js"] +CL["cloud.js"] +SY["sync.js"] +end +subgraph "Billing" +ENT["entitlement.js"] +BILL["billing.js"] +end +subgraph "DB Schema" +S1["001_schema.sql"] +S2["002_paypal_fulfillment.sql"] +end +AP --> ST +AP --> LS +AP --> CL +CL --> SB +SY --> SB +SY --> LS +ENT --> BILL +ST --> ENT +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- AccountPage: Central UI for profile editing, exporting/importing profile data, and deleting the account. It orchestrates validation, persistence, and cloud operations. +- Auth integration: Provides authentication context and user identity used by AccountPage and other modules. +- Store: Exposes current user and profile state; updates propagate to UI and services. +- Storage: Manages local preferences and cached profile snapshots for offline use. +- Cloud/Sync: Handles remote profile read/write and conflict resolution across devices. +- Entitlement/Billing: Determines feature access based on subscription status. + +Key responsibilities: +- Profile editing: Validate inputs, update local state, persist locally, and push changes to the cloud. +- Export/Import: Generate downloadable profile exports and import from files with validation and rollback on failure. +- Account deletion: Remove local data and request server-side deletion with confirmation and error handling. + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +## Architecture Overview +The account and profile system follows a layered architecture: +- Presentation layer (AccountPage) collects user input and triggers actions. +- State layer (store) holds current user and profile, broadcasting updates. +- Persistence layer (storage) writes preferences and cached data to local storage. +- Sync layer (sync + cloud) coordinates with Supabase for remote profile storage and conflict resolution. +- Identity and billing layers provide authentication and entitlement checks. + +```mermaid +sequenceDiagram +participant U as "User" +participant AP as "AccountPage" +participant ST as "Store" +participant LS as "Local Storage" +participant SY as "Sync Engine" +participant CL as "Cloud Helpers" +participant SB as "Supabase Client" +U->>AP : Edit profile fields +AP->>ST : Update profile state +ST->>LS : Persist preferences/cache +AP->>SY : Request cloud sync +SY->>CL : Prepare payload +CL->>SB : Write profile remotely +SB-->>CL : Acknowledge +CL-->>SY : Success/Failure +SY-->>AP : Sync result +AP-->>U : Show success or error +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### AccountPage Component +Responsibilities: +- Profile editing: Validates inputs, updates store, persists locally, and triggers cloud sync. +- Data export: Generates a structured export file from the current profile. +- Data import: Reads an exported file, validates schema, applies changes, and rolls back on errors. +- Account deletion: Confirms deletion, clears local data, and requests server-side removal. + +Validation rules: +- Required fields: Ensure essential profile attributes are present and non-empty. +- Format constraints: Enforce email format, name length limits, and allowed characters. +- Consistency checks: Prevent duplicate entries and ensure referential integrity within the profile. + +Error handling: +- Network failures: Retry with backoff and surface actionable messages. +- Validation errors: Highlight invalid fields and prevent submission until fixed. +- Import failures: Abort partial imports and restore previous state. + +```mermaid +flowchart TD +Start(["Open Account Page"]) --> LoadProfile["Load current profile
from store/local"] +LoadProfile --> EditMode{"Edit mode?"} +EditMode --> |Yes| ValidateInputs["Validate inputs"] +ValidateInputs --> Valid{"All valid?"} +Valid --> |No| ShowErrors["Show field-level errors"] +Valid --> |Yes| SaveLocal["Persist to local storage"] +SaveLocal --> SyncRemote["Trigger cloud sync"] +SyncRemote --> SyncOK{"Sync success?"} +SyncOK --> |Yes| ConfirmSave["Confirm save"] +SyncOK --> |No| HandleSyncErr["Handle sync error"] +EditMode --> |No| ExportFlow["Export profile"] +ExportFlow --> DownloadFile["Generate and download export"] +Start --> ImportFlow["Import profile"] +ImportFlow --> ReadFile["Read uploaded file"] +ReadFile --> ValidateSchema["Validate schema"] +ValidateSchema --> SchemaOK{"Valid?"} +SchemaOK --> |No| Rollback["Rollback and show error"] +SchemaOK --> |Yes| ApplyChanges["Apply changes to store"] +ApplyChanges --> SaveLocal +Start --> DeleteFlow["Delete account"] +DeleteFlow --> ConfirmDelete["Confirm deletion"] +ConfirmDelete --> ClearLocal["Clear local data"] +ClearLocal --> RequestServerDel["Request server-side deletion"] +RequestServerDel --> Done(["Done"]) +ConfirmSave --> Done +HandleSyncErr --> Done +DownloadFile --> Done +Rollback --> Done +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) + +### Profile Data Structure +Typical profile fields include: +- Identity: user ID, display name, email, avatar URL. +- Preferences: theme, language, notification toggles, default view modes. +- Subscription: plan type, expiry date, feature flags. +- Metadata: created_at, updated_at, version/timestamp for sync. + +Data model relationships: +- The profile is owned by the authenticated user and may reference entitlement records for billing features. + +```mermaid +erDiagram +USER { +uuid id PK +string email UK +string display_name +string avatar_url +timestamp created_at +timestamp updated_at +} +PROFILE { +uuid id PK +uuid user_id FK +jsonb preferences +enum plan_type +timestamp plan_expiry +int version +timestamp updated_at +} +USER ||--o{ PROFILE : has_one +``` + +**Diagram sources** +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Settings and Preference Management +- Local preferences: Stored via storage utilities for fast access and offline availability. +- Synced preferences: Pushed to cloud when online; conflicts resolved using timestamps or version numbers. +- Feature flags: Derived from entitlements and billing status. + +Operations: +- Read: Retrieve merged preferences from local cache and remote source. +- Write: Update local store, persist immediately, schedule background sync. +- Merge: On conflict, prefer newer timestamp or apply deterministic merge rules. + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [entitlement.js](file://src/lib/entitlement.js) + +### Data Export and Import +Export: +- Collects current profile and preferences into a structured format. +- Generates a downloadable file for backup or migration. + +Import: +- Parses uploaded file and validates against expected schema. +- Applies changes atomically; on failure, restores previous state. + +```mermaid +sequenceDiagram +participant U as "User" +participant AP as "AccountPage" +participant CSV as "CSV Utilities" +participant ST as "Store" +participant LS as "Local Storage" +participant SY as "Sync Engine" +U->>AP : Click Export +AP->>CSV : Build export payload +CSV-->>AP : File blob +AP-->>U : Download file +U->>AP : Upload import file +AP->>CSV : Parse and validate +CSV-->>AP : Parsed profile +AP->>ST : Apply changes +AP->>LS : Persist locally +AP->>SY : Trigger sync +SY-->>AP : Result +AP-->>U : Success or error +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +### Account Deletion +Deletion flow: +- Confirmation dialog to prevent accidental loss. +- Clear all local data (preferences, cached profile). +- Request server-side deletion via cloud helpers. +- Notify user of success or retry on failure. + +```mermaid +sequenceDiagram +participant U as "User" +participant AP as "AccountPage" +participant LS as "Local Storage" +participant CL as "Cloud Helpers" +participant SB as "Supabase Client" +U->>AP : Confirm delete +AP->>LS : Clear local data +AP->>CL : Request account deletion +CL->>SB : Delete user/profile records +SB-->>CL : Acknowledge +CL-->>AP : Success/Failure +AP-->>U : Show result +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +### Authentication and Entitlements +- Authentication provides the user identity used by AccountPage and sync processes. +- Entitlements determine access to premium features based on billing status. +- Billing integration manages subscriptions and fulfillment events. + +```mermaid +classDiagram +class Auth { ++currentUser ++login() ++logout() +} +class Entitlement { ++checkFeature(feature) bool ++refresh() void +} +class Billing { ++createCheckout() ++handleWebhook(event) +} +Auth --> Entitlement : "provides user context" +Entitlement --> Billing : "reads subscription state" +``` + +**Diagram sources** +- [auth.jsx](file://src/auth.jsx) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +## Dependency Analysis +Inter-module dependencies: +- AccountPage depends on store, storage, cloud, and sync for full CRUD and export/import/deletion workflows. +- Sync depends on cloud and supabase clients to perform remote operations. +- Entitlement depends on billing to reflect subscription state. +- Storage is used by both UI and sync for local caching. + +```mermaid +graph LR +AP["AccountPage.jsx"] --> ST["store.jsx"] +AP --> LS["storage.js"] +AP --> CL["cloud.js"] +AP --> SY["sync.js"] +SY --> CL +SY --> SB["supabase.js"] +ENT["entitlement.js"] --> BILL["billing.js"] +ST --> ENT +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +## Performance Considerations +- Debounce profile edits to reduce frequent writes and network calls. +- Batch sync operations to minimize API overhead. +- Cache frequently accessed preferences locally to avoid redundant reads. +- Use optimistic UI updates with rollback on failure to improve perceived responsiveness. +- Limit export size by allowing selective fields or pagination if needed. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Validation errors: Check required fields and formats; re-submit after corrections. +- Sync failures: Verify connectivity; retry with exponential backoff; inspect error codes. +- Import failures: Validate file schema; ensure no missing required columns; attempt re-import. +- Deletion not reflected: Confirm server-side deletion; clear local cache and reload. + +Operational tips: +- Enable detailed logs during development to trace sync and storage operations. +- Use export to recover from corrupted local state before attempting import. +- Monitor entitlement refresh cycles to ensure feature flags are up-to-date. + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [sync.js](file://src/lib/sync.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) + +## Conclusion +ApplyGuard PH’s account and profile system combines robust local persistence with reliable cloud synchronization, providing a seamless experience across devices. The AccountPage component centralizes profile editing, export/import, and deletion, while respecting validation, error handling, and privacy requirements. Entitlements and billing integrate to control feature access, and the database schema supports secure, consistent storage of user data. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Privacy, Retention, and GDPR Features +- Data minimization: Only collect necessary profile fields. +- Consent and transparency: Inform users about data usage and retention periods. +- Right to access: Provide export functionality for personal data. +- Right to erasure: Support account deletion with server-side cleanup. +- Data portability: Allow structured export for easy migration. +- Security: Encrypt sensitive data at rest and in transit; enforce access controls. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Backend Services (Supabase).md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Backend Services (Supabase).md new file mode 100644 index 0000000..41ad61a --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Backend Services (Supabase).md @@ -0,0 +1,410 @@ +# Backend Services (Supabase) + + +**Referenced Files in This Document** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/config.toml](file://supabase/config.toml) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion +10. Appendices + +## Introduction +This document describes the backend services for ApplyGuard PH built on Supabase Edge Functions and PostgreSQL. It covers: +- All edge functions including AI proxy, billing handlers, and utility services +- Database schema design, table relationships, and indexing strategies +- Security policies, row-level security rules, and API access controls +- Shared utilities library, common patterns, and best practices +- Deployment configuration, environment management, and monitoring approaches + +The goal is to provide a comprehensive reference for developers integrating with or extending the backend. + +## Project Structure +The backend is organized under supabase/: +- functions: Deno-based Edge Functions implementing business logic + - ai-proxy: Proxies requests to external AI providers + - create-checkout: Creates checkout sessions via PayMongo + - paymongo-webhook: Processes PayMongo payment webhooks + - cancel-subscription: Cancels subscriptions + - capture-paypal-order: Captures PayPal orders + - create-paypal-order: Creates PayPal orders + - paypal-webhook: Processes PayPal webhooks + - download-message-pack: Generates downloadable message packs + - _shared: Shared libraries used across functions +- migrations: SQL migrations defining schema and RLS policies +- config.toml: Supabase project configuration + +```mermaid +graph TB +subgraph "Supabase" +FE["Frontend"] --> EF1["Edge Function: ai-proxy"] +FE --> EF2["Edge Function: create-checkout"] +FE --> EF3["Edge Function: paymongo-webhook"] +FE --> EF4["Edge Function: cancel-subscription"] +FE --> EF5["Edge Function: create-paypal-order"] +FE --> EF6["Edge Function: capture-paypal-order"] +FE --> EF7["Edge Function: paypal-webhook"] +FE --> EF8["Edge Function: download-message-pack"] +EF1 --> DB["PostgreSQL"] +EF2 --> DB +EF3 --> DB +EF4 --> DB +EF5 --> DB +EF6 --> DB +EF7 --> DB +EF8 --> DB +end +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Core Components +- AI Proxy: Forwards prompts to external AI APIs securely, enforcing rate limits and logging. +- Billing Handlers: Create checkout sessions, manage PayPal orders, and process webhooks from PayMongo and PayPal. +- Utility Services: Shared HTTP client, entitlement checks, PayPal SDK wrappers, and prompt templates. + +Key responsibilities: +- Enforce authentication and authorization at function boundaries +- Validate inputs and responses +- Persist state changes in PostgreSQL with proper RLS +- Provide consistent error handling and observability + +**Section sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Architecture Overview +High-level flow: +- Frontend calls Edge Functions via Supabase client +- Functions authenticate users, validate payloads, and interact with PostgreSQL +- External integrations include AI providers, PayMongo, and PayPal +- Webhooks update subscription and payment states + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant EF as "Create Checkout Function" +participant PG as "PostgreSQL" +participant PM as "PayMongo API" +Client->>EF : "POST /create-checkout" +EF->>PG : "Validate user and plan" +EF->>PM : "Create checkout session" +PM-->>EF : "Checkout URL" +EF-->>Client : "Redirect URL" +``` + +**Diagram sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### AI Proxy Function +Purpose: +- Securely proxy AI requests to external providers +- Enforce per-user quotas and feature flags +- Log usage metrics and errors + +Responsibilities: +- Authenticate request and resolve user context +- Validate input payload and allowed models +- Forward request with configured headers and timeouts +- Stream or buffer response based on provider capabilities +- Record usage events and enforce rate limits + +Error handling: +- Normalize provider errors into consistent formats +- Return appropriate HTTP status codes +- Avoid leaking sensitive provider details + +Security: +- Restrict endpoints by entitlements +- Sanitize prompts and strip disallowed fields +- Enforce CORS and origin checks + +Performance: +- Use connection pooling where applicable +- Cache repeated prompts if safe +- Implement retries with backoff for transient failures + +**Section sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Billing: PayMongo Integration +Functions: +- create-checkout: Initiates a PayMongo checkout session +- paymongo-webhook: Confirms payments and updates subscriptions + +Flow: +- Client requests checkout creation with plan and metadata +- Function validates entitlements and creates checkout session +- Webhook receives payment confirmation and updates database + +Idempotency: +- Deduplicate webhook events using unique IDs +- Ensure idempotent updates to subscription records + +Security: +- Verify webhook signatures +- Validate amounts and currency server-side + +Data persistence: +- Store checkout sessions, payments, and subscription records +- Maintain audit trails for billing events + +**Section sources** +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Billing: PayPal Integration +Functions: +- create-paypal-order: Creates a PayPal order +- capture-paypal-order: Captures an approved order +- paypal-webhook: Handles PayPal event notifications + +Flow: +- Client initiates order creation with plan details +- Function creates PayPal order and returns order ID +- On approval, client triggers capture +- Webhooks update order and subscription state + +Idempotency: +- Guard against duplicate captures and webhook processing +- Track order lifecycle states + +Security: +- Validate webhook events and signatures +- Confirm order totals before capture + +Data persistence: +- Store orders, captures, and related metadata +- Link orders to user accounts and plans + +**Section sources** +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Subscription Cancellation +Function: +- cancel-subscription: Cancels active subscriptions and revokes entitlements + +Behavior: +- Validates cancellation eligibility +- Updates subscription status and effective dates +- Ensures downstream entitlements are revoked + +Idempotency: +- Prevent multiple cancellations for the same subscription + +Auditability: +- Record cancellation reasons and timestamps + +**Section sources** +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Download Message Pack +Function: +- download-message-pack: Generates and serves a compressed archive of messages + +Responsibilities: +- Validate user permissions +- Assemble messages into a package +- Stream or return file content with correct MIME type + +Performance: +- Use streaming for large payloads +- Limit size and scope of generated archives + +**Section sources** +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) + +### Shared Utilities Library +Components: +- http.ts: Common HTTP client with retry, timeout, and error normalization +- entitlement.ts: Checks user entitlements and feature flags +- paypal.ts: PayPal SDK wrapper and helpers +- paypal-runtime.ts: Runtime configuration for PayPal integration +- prompts.ts: Centralized prompt templates and validation + +Patterns: +- Consistent error shapes and logging +- Environment-driven configuration +- Reusable validation and sanitization + +Best practices: +- Keep shared modules small and focused +- Export typed interfaces for consumers +- Unit test critical paths + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Dependency Analysis +Internal dependencies: +- Functions depend on shared utilities for HTTP, entitlements, and PayPal operations +- Migrations define tables and constraints consumed by functions + +External dependencies: +- AI providers (via ai-proxy) +- PayMongo API (checkout and webhooks) +- PayPal API (orders, captures, webhooks) + +```mermaid +graph LR +A["ai-proxy/index.ts"] --> S1["_shared/http.ts"] +B["create-checkout/index.ts"] --> S2["_shared/entitlement.ts"] +C["paymongo-webhook/index.ts"] --> S2 +D["cancel-subscription/index.ts"] --> S2 +E["create-paypal-order/index.ts"] --> S3["_shared/paypal.ts"] +F["capture-paypal-order/index.ts"] --> S3 +G["paypal-webhook/index.ts"] --> S3 +H["download-message-pack/index.ts"] --> S1 +I["migrations/001_schema.sql"] --> J["Tables & Policies"] +K["migrations/002_paypal_fulfillment.sql"] --> J +``` + +**Diagram sources** +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Minimize cold starts by keeping function bundles lean and avoiding heavy dependencies +- Use streaming for large downloads and long-running AI responses +- Implement retries with exponential backoff for external API calls +- Cache frequently accessed data when safe and consistent +- Index high-cardinality columns used in frequent queries +- Batch writes where possible and avoid N+1 query patterns + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: Ensure valid tokens and correct scopes; verify RLS policies allow access +- Webhook signature mismatches: Check secret configuration and timestamp tolerances +- Idempotency violations: Deduplicate events using unique IDs and transactional updates +- Rate limiting: Monitor provider quotas and implement backoff strategies +- Schema mismatches: Align migration versions with deployed functions and clients + +Operational tips: +- Enable structured logging with correlation IDs +- Add health checks for external dependencies +- Use feature flags to roll out risky changes gradually + +**Section sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +ApplyGuard PH’s Supabase backend provides a secure, extensible foundation for AI features and billing workflows. The modular function architecture, robust shared utilities, and well-defined schema enable reliable operation and clear separation of concerns. Following the recommended patterns for security, performance, and observability will help maintain stability as the system scales. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Database Schema Design and Relationships +- Users and accounts: Core identity and profile data +- Plans and subscriptions: Define tiers and lifecycle states +- Payments and orders: Capture transactions and linkage to subscriptions +- Audit logs: Track key actions and changes + +Indexing strategy: +- Primary keys on all entities +- Unique indexes on natural keys (e.g., email, external IDs) +- Composite indexes for frequent filter combinations (e.g., user_id + status) +- Partial indexes for hot paths (e.g., active subscriptions) + +Row-Level Security (RLS): +- Enforce user-scoped access on personal data +- Restrict admin-only tables to service roles +- Validate ownership on updates and deletes + +API Access Controls: +- Require authenticated requests for protected functions +- Validate payloads and sanitize inputs +- Apply least-privilege principles for service accounts + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Deployment Configuration and Environment Management +- Supabase configuration: Managed via config.toml +- CI/CD pipeline: GitHub Actions workflow for Supabase deployments +- Environment variables: Secrets for third-party APIs stored securely +- Version control: Migrations tracked and applied through CI + +Monitoring approaches: +- Centralized logging with function-level correlation IDs +- Metrics collection for latency, errors, and throughput +- Alerting on critical failures and webhook anomalies + +**Section sources** +- [supabase/config.toml](file://supabase/config.toml) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Database Schema.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Database Schema.md new file mode 100644 index 0000000..434a597 --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Database Schema.md @@ -0,0 +1,635 @@ +# Database Schema + + +**Referenced Files in This Document** +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + + +## Update Summary +**Changes Made** +- Updated PayPal Fulfillment section to reflect expanded payment processing capabilities from Haiku 4.5 migration +- Added documentation for new trial and usage ledger tables that enhance analytics capabilities +- Enhanced data access controls section with new table-specific policies +- Updated architecture diagrams to include new fulfillment and ledger components +- Expanded performance considerations for the new high-volume ledger tables + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the database schema and data access model for ApplyGuard PH using Supabase. It focuses on the entity-relationship model across users, applications, offers, subscriptions, and analytics-related data. The schema has been enhanced with PayPal fulfillment tables and trial/usage ledger tables from the Haiku 4.5 migration, significantly expanding payment processing and analytics capabilities. It also covers indexing strategies, query optimization patterns, data access controls, migration management, version control practices, backup/restore procedures, sample queries, common data access patterns, and performance considerations for large datasets. + +## Project Structure +The database is managed via Supabase migrations under the supabase directory. The application code interacts with the database through a client library and serverless functions for billing and entitlements. The recent Haiku 4.5 migration has added comprehensive PayPal fulfillment tracking and detailed usage analytics through ledger tables. + +```mermaid +graph TB +subgraph "Supabase" +CFG["config.toml"] +MIG1["migrations/001_schema.sql"] +MIG2["migrations/002_paypal_fulfillment.sql"] +end +subgraph "Frontend" +JS_SUP["src/lib/supabase.js"] +JS_BILL["src/lib/billing.js"] +JS_ENT["src/lib/entitlement.js"] +end +subgraph "Edge Functions" +ENT_TS["functions/_shared/entitlement.ts"] +PM_WEBHOOK["functions/paymongo-webhook/index.ts"] +PP_WEBHOOK["functions/paypal-webhook/index.ts"] +CANCEL_SUB["functions/cancel-subscription/index.ts"] +end +CFG --> MIG1 +CFG --> MIG2 +JS_SUP --> MIG1 +JS_SUP --> MIG2 +JS_BILL --> PM_WEBHOOK +JS_BILL --> PP_WEBHOOK +JS_ENT --> ENT_TS +PM_WEBHOOK --> MIG1 +PM_WEBHOOK --> MIG2 +PP_WEBHOOK --> MIG1 +PP_WEBHOOK --> MIG2 +CANCEL_SUB --> MIG1 +CANCEL_SUB --> MIG2 +``` + +**Diagram sources** +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +**Section sources** +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Core Components +This section outlines the primary entities and their relationships as implemented by the migrations: + +- Users + - Identity and profile information tied to Supabase Auth. + - Typically includes fields such as user id, email, display name, and timestamps. + - Relationships: one-to-many with applications, subscriptions, and analytics events. + +- Applications + - Records representing user-uploaded or analyzed documents (e.g., job offers). + - Fields include identifiers, metadata, analysis results, status, and timestamps. + - Relationships: many-to-one with users; may have child records for follow-ups or notes. + +- Offers + - Structured representation of offer details extracted from applications. + - Includes compensation, role, company, start date, benefits, and other negotiated terms. + - Relationships: one-to-one or one-to-many with applications depending on normalization. + +- Subscriptions + - Billing state per user, including plan type, status, provider references, and renewal dates. + - Relationships: one-to-one with users; linked to payment provider records. + +- Analytics + - Event-driven logs capturing user interactions, feature usage, and system metrics. + - Fields include event type, payload, timestamp, and user context. + - Relationships: many-to-one with users; append-only table. + +- Payment Provider Fulfillment (PayPal) + - Records created by webhooks to reconcile payments and fulfill subscription changes. + - Includes provider order/subscription ids, amounts, currency, status, and audit fields. + - Relationships: one-to-one with subscriptions; referenced by webhook handlers. + +- Trial and Usage Ledger + - Detailed tracking of trial periods and feature usage for analytics and billing purposes. + - Captures granular usage events, trial period boundaries, and consumption metrics. + - Relationships: linked to users and subscriptions; supports complex usage analytics. + +```mermaid +erDiagram +USERS { +uuid id PK +string email +string display_name +timestamp created_at +timestamp updated_at +} +APPLICATIONS { +uuid id PK +uuid user_id FK +jsonb metadata +jsonb analysis_results +enum status +timestamp created_at +timestamp updated_at +} +OFFERS { +uuid id PK +uuid application_id FK +jsonb terms +decimal total_compensation +string currency +date start_date +boolean accepted +timestamp created_at +timestamp updated_at +} +SUBSCRIPTIONS { +uuid id PK +uuid user_id FK +enum plan_type +enum status +string provider_subscription_id +string provider_customer_id +timestamp current_period_end +timestamp created_at +timestamp updated_at +} +ANALYTICS_EVENTS { +uuid id PK +uuid user_id FK +string event_type +jsonb payload +timestamp occurred_at +} +PAYPAL_FULFILLMENT { +uuid id PK +uuid subscription_id FK +string provider_order_id +string provider_subscription_id +decimal amount +string currency +enum status +jsonb raw_event +timestamp processed_at +} +TRIAL_LEDGER { +uuid id PK +uuid user_id FK +uuid subscription_id FK +enum trial_type +timestamp trial_start +timestamp trial_end +enum trial_status +jsonb trial_details +timestamp created_at +} +USAGE_LEDGER { +uuid id PK +uuid user_id FK +uuid subscription_id FK +string feature_name +decimal usage_amount +string usage_unit +timestamp usage_timestamp +jsonb usage_metadata +timestamp created_at +} +USERS ||--o{ APPLICATIONS : "owns" +USERS ||--o{ SUBSCRIPTIONS : "has" +USERS ||--o{ ANALYTICS_EVENTS : "generates" +USERS ||--o{ TRIAL_LEDGER : "trial_history" +USERS ||--o{ USAGE_LEDGER : "usage_tracking" +APPLICATIONS ||--o| OFFERS : "contains" +SUBSCRIPTIONS ||--o{ PAYPAL_FULFILLMENT : "fulfilled_by" +SUBSCRIPTIONS ||--o{ TRIAL_LEDGER : "trial_management" +SUBSCRIPTIONS ||--o{ USAGE_LEDGER : "consumption_tracking" +``` + +[No diagram sources since this diagram is conceptual and not mapped to specific file lines] + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +Data flows between the frontend, Supabase Edge Functions, and the database are orchestrated through migrations and function handlers. Webhooks from payment providers trigger fulfillment logic that updates subscription states and creates audit trails. The Haiku 4.5 enhancement adds comprehensive trial management and detailed usage tracking for advanced analytics and billing reconciliation. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Supabase as "Supabase Client" +participant DB as "Database" +participant PMWebhook as "Paymongo Webhook Function" +participant PPWebhook as "PayPal Webhook Function" +participant Ent as "Entitlement Function" +Client->>Supabase : "Create checkout / update subscription" +Supabase->>DB : "Insert/update subscriptions" +PMWebhook->>DB : "Upsert PayPal/Paymongo fulfillment records" +PPWebhook->>DB : "Upsert PayPal fulfillment records" +Client->>Ent : "Check entitlements" +Ent->>DB : "Read subscriptions and related records" +DB-->>Ent : "Subscription state" +Ent-->>Client : "Feature access decision" +Note over DB : New Trial & Usage Ledger Tables
Track trial periods and feature consumption +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Users +- Purpose: Represents authenticated users and basic profile attributes. +- Key fields: + - id: Primary key, typically UUID. + - email: Unique identifier for login. + - display_name: Human-readable name. + - created_at, updated_at: Audit timestamps. +- Constraints: + - Primary key on id. + - Unique constraint on email. +- Indexing: + - Index on email for fast lookups. + - Optional index on created_at for time-based queries. +- Data access controls: + - Row-Level Security (RLS) policies restrict reads/writes to the current user's row. +- Common queries: + - Fetch profile by id or email. + - Update display_name or profile metadata. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Applications +- Purpose: Stores uploaded or analyzed documents and their processing state. +- Key fields: + - id: Primary key, UUID. + - user_id: Foreign key referencing users.id. + - metadata: JSONB for flexible document attributes. + - analysis_results: JSONB for AI or scoring outputs. + - status: Enum indicating lifecycle (e.g., pending, analyzed, archived). + - created_at, updated_at: Audit timestamps. +- Constraints: + - Primary key on id. + - Foreign key on user_id with cascade behavior as appropriate. +- Indexing: + - Index on user_id for user-scoped queries. + - GIN index on analysis_results if querying nested JSON keys frequently. +- Data access controls: + - RLS policies ensure users can only access their own applications. +- Common queries: + - List applications for a user ordered by created_at. + - Retrieve analysis results by application id. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Offers +- Purpose: Captures structured offer details derived from applications. +- Key fields: + - id: Primary key, UUID. + - application_id: Foreign key referencing applications.id. + - terms: JSONB for flexible offer structure. + - total_compensation: Numeric value for compensation. + - currency: ISO currency code. + - start_date: Date field. + - accepted: Boolean flag. + - created_at, updated_at: Audit timestamps. +- Constraints: + - Primary key on id. + - Foreign key on application_id with referential integrity. +- Indexing: + - Index on application_id for join performance. + - Optional index on start_date for range queries. +- Data access controls: + - RLS policies propagate from applications to offers via user_id linkage. +- Common queries: + - Get latest offer for an application. + - Filter offers by acceptance status and date range. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Subscriptions +- Purpose: Tracks user subscription plans and billing state. +- Key fields: + - id: Primary key, UUID. + - user_id: Foreign key referencing users.id. + - plan_type: Enum (e.g., free, pro). + - status: Enum (e.g., active, canceled, past_due). + - provider_subscription_id: External provider reference. + - provider_customer_id: External customer reference. + - current_period_end: Timestamp for billing cycle. + - created_at, updated_at: Audit timestamps. +- Constraints: + - Primary key on id. + - Foreign key on user_id. + - Unique constraints on provider_subscription_id to avoid duplicates. +- Indexing: + - Index on user_id for quick subscription lookup. + - Index on status for filtering active subscriptions. +- Data access controls: + - RLS policies restrict access to the owning user. +- Common queries: + - Check if a user has an active subscription. + - Retrieve subscription details for billing UI. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Analytics Events +- Purpose: Append-only log of user interactions and system events. +- Key fields: + - id: Primary key, UUID. + - user_id: Foreign key referencing users.id. + - event_type: String categorizing the event. + - payload: JSONB for event-specific data. + - occurred_at: Timestamp of the event. +- Constraints: + - Primary key on id. + - Foreign key on user_id. +- Indexing: + - Index on user_id and occurred_at for time-series queries. + - GIN index on payload if querying nested fields. +- Data access controls: + - RLS policies allow users to read their own events; write access controlled by service roles or functions. +- Common queries: + - Count events by type over a time window. + - Retrieve recent events for a user. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### PayPal Fulfillment +- Purpose: Reconciles PayPal webhook events to update subscription state and maintain audit trails. +- Key fields: + - id: Primary key, UUID. + - subscription_id: Foreign key referencing subscriptions.id. + - provider_order_id: External order identifier. + - provider_subscription_id: External subscription identifier. + - amount: Numeric value. + - currency: ISO currency code. + - status: Enum (e.g., captured, refunded, failed). + - raw_event: JSONB storing the original webhook payload. + - processed_at: Timestamp when fulfilled. +- Constraints: + - Primary key on id. + - Foreign key on subscription_id. + - Unique constraints on provider_order_id/provider_subscription_id to prevent duplicate processing. +- Indexing: + - Index on subscription_id for joins. + - Index on processed_at for audit queries. +- Data access controls: + - Write access restricted to webhook functions; read access limited to admin/service roles. +- Common queries: + - Find fulfillment records by external ids. + - Audit reconciliation by subscription and date range. + +**Updated** Enhanced with improved idempotency handling and expanded status tracking from Haiku 4.5 migration. + +**Section sources** +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Trial and Usage Ledger +- Purpose: Comprehensive tracking of trial periods and feature usage for advanced analytics and billing reconciliation. +- Key fields: + - id: Primary key, UUID. + - user_id: Foreign key referencing users.id. + - subscription_id: Foreign key referencing subscriptions.id. + - trial_type: Enum defining trial category (e.g., free_trial, promotional). + - trial_start, trial_end: Timestamps defining trial period boundaries. + - trial_status: Enum tracking trial lifecycle (e.g., active, expired, converted). + - trial_details: JSONB for flexible trial configuration and metadata. + - feature_name: Identifier for tracked features. + - usage_amount: Decimal value for consumption quantity. + - usage_unit: Unit of measurement (e.g., requests, storage_gb). + - usage_timestamp: When the usage occurred. + - usage_metadata: JSONB for additional usage context. +- Constraints: + - Primary keys on id. + - Foreign keys on user_id and subscription_id. + - Unique constraints on trial combinations to prevent overlapping trials. +- Indexing: + - Composite indexes on user_id + subscription_id for relationship queries. + - Time-based indexes on trial_start/trial_end and usage_timestamp for temporal queries. + - GIN indexes on JSONB columns for flexible querying. +- Data access controls: + - RLS policies restrict access to user's own trial and usage data. + - Service role access for billing and analytics functions. +- Common queries: + - Calculate trial conversion rates by subscription type. + - Aggregate usage metrics by feature and time period. + - Identify users approaching trial expiration. + +**New** Added from Haiku 4.5 migration to support advanced trial management and detailed usage analytics. + +**Section sources** +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Data Access Controls and RLS Policies +- Principle: Enforce row-level security so users can only access their own data. +- Typical policies: + - SELECT: Allow users to read rows where user_id matches auth.uid(). + - INSERT: Allow users to insert rows with user_id set to auth.uid(). + - UPDATE/DELETE: Restrict modifications to the owning user. +- Service roles: + - Use Supabase service role for backend functions (webhooks, entitlement checks) to bypass RLS when necessary. +- Best practices: + - Centralize policy definitions in migrations. + - Validate inputs at the function layer before writes. + - Implement separate policies for high-volume ledger tables to optimize performance. + +**Updated** Enhanced with specific policies for new trial and usage ledger tables, including optimized access patterns for analytics queries. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Migration Management and Version Control +- Tooling: + - Supabase CLI manages migrations defined in SQL files under supabase/migrations. +- Workflow: + - Create new migration files with descriptive names and incremental changes. + - Apply migrations locally and to production via CI/CD. +- Version control: + - Each migration is a separate file; commit messages should describe schema changes. +- Rollback strategy: + - Maintain backward-compatible migrations; avoid destructive changes without careful planning. + - The Haiku 4.5 migration demonstrates proper additive schema evolution with new tables and indexes. + +**Updated** Enhanced with examples from the Haiku 4.5 migration showing best practices for adding complex new functionality. + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Backup and Restore Procedures +- Backups: + - Use Supabase dashboard or CLI to schedule automated backups. + - Export snapshots periodically for disaster recovery. +- Restore: + - Restore from snapshot to a staging environment first. + - Validate schema and data integrity before promoting to production. +- Retention: + - Define retention policies aligned with compliance requirements. + - Consider partitioning strategies for high-volume ledger tables to manage backup sizes. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +The following diagram shows how components depend on each other and interact with the database: + +```mermaid +graph LR +JS_SUP["src/lib/supabase.js"] --> DB["Database"] +JS_BILL["src/lib/billing.js"] --> PMWEB["paymongo-webhook/index.ts"] +JS_BILL --> PPWEB["paypal-webhook/index.ts"] +JS_ENT["src/lib/entitlement.js"] --> ENTTS["_shared/entitlement.ts"] +PMWEB --> DB +PPWEB --> DB +ENTTS --> DB +MIG1["migrations/001_schema.sql"] --> DB +MIG2["migrations/002_paypal_fulfillment.sql"] --> DB +DB --> TRIAL["Trial & Usage Ledger Tables"] +DB --> FULFILL["Enhanced PayPal Fulfillment"] +``` + +**Diagram sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Indexing strategies: + - Add indexes on foreign keys (user_id, application_id, subscription_id). + - Use GIN indexes on JSONB columns when querying nested keys frequently. + - Composite indexes for common filter combinations (e.g., user_id + occurred_at). + - **New**: Implement specialized indexes for trial and usage ledger tables including composite indexes on (user_id, subscription_id, usage_timestamp) for efficient time-series queries. +- Query optimization: + - Prefer selective filters to reduce scan size. + - Avoid SELECT *; project only required fields. + - Use pagination for large result sets. + - **New**: For high-volume ledger tables, implement query patterns that leverage time-based partitioning and use materialized views for complex aggregations. +- Partitioning: + - Consider partitioning analytics_events by time for high-volume logging. + - **New**: Implement time-based partitioning for usage_ledger and paypal_fulfillment tables to handle large datasets efficiently. +- Connection pooling: + - Use connection pooling for serverless functions to reduce overhead. +- Materialized views: + - For heavy aggregations (e.g., monthly analytics), use materialized views refreshed periodically. + - **New**: Create materialized views for trial conversion metrics and usage summary reports. +- **New**: Ledger table optimization: + - Use batch inserts for high-frequency usage tracking. + - Implement archival strategies for historical trial and usage data. + - Monitor query performance on JSONB columns and consider denormalization for frequently accessed fields. + +**Updated** Enhanced with specific performance considerations for the new high-volume trial and usage ledger tables introduced in Haiku 4.5. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +- Webhook idempotency: + - Ensure fulfillment functions handle duplicate events gracefully using unique provider ids. + - **New**: Verify that trial and usage ledger entries are properly deduplicated to prevent double-counting. +- Subscription state consistency: + - Verify that webhook handlers update both fulfillment records and subscription status atomically. + - **New**: Ensure trial status transitions are synchronized with subscription state changes. +- RLS policy issues: + - Confirm policies align with expected access patterns; test with service role vs. user role. + - **New**: Test RLS policies specifically for new ledger tables to ensure proper data isolation. +- Migration conflicts: + - Review migration ordering and ensure no destructive changes break existing clients. + - **New**: Validate that Haiku 4.5 migration doesn't conflict with existing schema assumptions. +- **New**: Ledger table performance: + - Monitor query performance on high-volume usage tables and adjust indexing strategies as needed. + - Implement proper cleanup and archival processes for historical data. + +**Updated** Enhanced with troubleshooting guidance for the new trial and usage ledger functionality. + +**Section sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Conclusion +ApplyGuard PH's database schema centers around users, applications, offers, subscriptions, analytics events, and PayPal fulfillment records. The Haiku 4.5 migration has significantly enhanced the system with comprehensive trial management and detailed usage tracking through new ledger tables. Migrations define the schema and constraints, while RLS policies enforce secure access. Webhook functions manage billing state changes and create audit trails. Proper indexing, query design, and migration practices ensure scalability and reliability for the expanded payment processing and analytics capabilities. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Sample Queries +- Fetch a user's active subscription: + - Select subscriptions where user_id equals the current user and status is active. +- List applications for a user: + - Select applications where user_id equals the current user, ordered by created_at descending. +- Retrieve latest offer for an application: + - Join offers with applications and filter by application_id. +- Analytical aggregation: + - Group analytics_events by event_type and count occurrences within a time window. +- **New**: Trial conversion analysis: + - Calculate trial conversion rates by joining trial_ledger with subscription data and filtering by trial_status. +- **New**: Usage metrics aggregation: + - Sum usage_amount grouped by feature_name and time period for billing calculations. +- **New**: PayPal reconciliation: + - Match PayPal fulfillment records with subscription changes using provider IDs and amounts. + +**Updated** Added sample queries for the new trial and usage ledger functionality. + +[No sources needed since this section provides general guidance] + +### Common Data Access Patterns +- User-scoped reads: + - Always filter by user_id in queries. +- Append-only analytics: + - Insert events without updating existing rows. +- Idempotent webhooks: + - Upsert fulfillment records keyed by provider ids. +- **New**: Trial lifecycle management: + - Track trial status transitions with proper timestamp boundaries. +- **New**: Usage tracking patterns: + - Batch insert usage events with proper deduplication. + - Aggregate usage metrics for billing and analytics. + +**Updated** Added common data access patterns for the new trial and usage ledger functionality. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/AI Proxy Function.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/AI Proxy Function.md new file mode 100644 index 0000000..d3df960 --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/AI Proxy Function.md @@ -0,0 +1,314 @@ +# AI Proxy Function + + +**Referenced Files in This Document** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [auth.jsx](file://src/auth.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the AI proxy function that handles resume analysis and interview coaching requests. It explains how the Supabase Edge Function proxies requests to external AI services, manages API keys securely, validates inputs, enforces entitlements, and returns structured responses to the frontend. It also provides guidance on calling the proxy from React components, handling streaming when applicable, implementing retry logic, rate limiting, and security considerations for protecting AI service credentials. + +## Project Structure +The AI proxy is implemented as a Supabase Edge Function under supabase/functions/ai-proxy. The frontend uses client libraries and hooks to call this endpoint. Shared utilities handle HTTP interactions and entitlement checks. + +```mermaid +graph TB +subgraph "Frontend" +A["React App
Components"] +B["Client Library
ai.js"] +end +subgraph "Supabase Edge Functions" +C["AI Proxy Function
ai-proxy/index.ts"] +D["Shared HTTP Utilities
_shared/http.ts"] +E["Entitlement Checks
_shared/entitlement.ts"] +end +subgraph "External AI Services" +F["AI Provider API"] +end +A --> B +B --> C +C --> D +C --> E +C --> F +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [ai.js](file://src/lib/ai.js) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [ai.js](file://src/lib/ai.js) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Core Components +- AI Proxy Function: Receives authenticated requests, validates inputs, checks user entitlements, forwards prompts to external AI providers using secure environment variables, and returns structured JSON or streamed responses. +- Client Library (ai.js): Provides typed helpers to call the AI proxy with request payloads and parse responses. +- Shared HTTP Utilities: Encapsulate outbound HTTP calls, headers, timeouts, retries, and error mapping. +- Entitlement Module: Validates subscription or feature access before allowing AI usage. + +Key responsibilities: +- Authentication and authorization via Supabase session context. +- Input validation and sanitization for prompt content and parameters. +- Secure retrieval of AI provider credentials from environment variables. +- Outbound request construction and response normalization. +- Streaming support where applicable. +- Error handling and consistent error shapes. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [ai.js](file://src/lib/ai.js) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview +The AI proxy acts as a secure gateway between the frontend and external AI services. It ensures only authorized users can invoke AI features, enforces quotas, and centralizes credential management. + +```mermaid +sequenceDiagram +participant FE as "Frontend React App" +participant CL as "Client Library ai.js" +participant SF as "Supabase Edge Function
ai-proxy/index.ts" +participant ENT as "Entitlement Check
_shared/entitlement.ts" +participant HTTP as "HTTP Utils
_shared/http.ts" +participant AI as "External AI Service" +FE->>CL : Call analyzeResume / coachInterview +CL->>SF : POST /functions/v1/ai-proxy {user_id, prompt, options} +SF->>SF : Validate input & sanitize +SF->>ENT : Verify entitlements for user_id +ENT-->>SF : Allowed/Denied +alt Allowed +SF->>HTTP : Build outbound request with env secrets +HTTP->>AI : Forward request +AI-->>HTTP : Streamed or JSON response +HTTP-->>SF : Normalized payload +SF-->>CL : Structured response or stream +else Denied +SF-->>CL : 403 Forbidden with error code +end +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [ai.js](file://src/lib/ai.js) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### AI Proxy Function +Responsibilities: +- Parse and validate incoming request body fields such as user_id, prompt, and optional parameters (e.g., model, temperature). +- Enforce authentication by reading Supabase session context. +- Perform entitlement checks to ensure the user has access to AI features. +- Retrieve AI provider credentials from environment variables; never accept secrets from clients. +- Construct outbound requests to the AI provider with appropriate headers and payload. +- Support both JSON and streaming responses depending on provider capabilities. +- Normalize responses into a consistent schema for the frontend. +- Map provider errors to standardized error codes and messages. + +Security considerations: +- Do not expose provider API keys to the client. +- Validate and sanitize all inputs to prevent injection or abuse. +- Apply rate limiting per user or globally at the function level. +- Log minimal sensitive data; avoid logging full prompts or tokens. + +Error handling patterns: +- Return structured errors with codes like INVALID_INPUT, UNAUTHORIZED, FORBIDDEN, RATE_LIMITED, PROVIDER_ERROR. +- Include message and optional details for debugging while avoiding leaking secrets. + +Streaming behavior: +- If supported by the provider, forward server-sent events or chunked responses. +- Ensure the client library consumes streams correctly and reassembles partial outputs. + +Input validation rules: +- Required fields: user_id, prompt. +- Prompt length limits and allowed character sets. +- Optional parameters: model, max_tokens, temperature, top_p, with safe defaults and bounds. + +Rate limiting: +- Implement per-user and global limits using in-memory counters or external stores if needed. +- Return 429 with retry-after guidance when exceeded. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Client Library (ai.js) +Responsibilities: +- Provide functions to call the AI proxy endpoint with typed payloads. +- Handle authentication headers automatically using Supabase client. +- Parse JSON responses and normalize them into application models. +- Optionally consume streaming responses if the backend supports it. +- Expose retry helpers with exponential backoff and jitter. + +Usage examples: +- Resume analysis: call analyzeResume with resume text and options. +- Interview coaching: call coachInterview with questions and context. + +Retry logic: +- Retry transient errors (network timeouts, 5xx, 429) with backoff. +- Avoid retrying invalid input or permission errors. + +**Section sources** +- [ai.js](file://src/lib/ai.js) + +### Shared HTTP Utilities (_shared/http.ts) +Responsibilities: +- Centralize outbound HTTP configuration: timeouts, retries, headers. +- Inject AI provider credentials from environment variables. +- Normalize provider responses and errors. +- Support streaming transport when available. + +Configuration: +- Base URL and endpoints for the AI provider. +- Timeout durations and maximum retries. +- Header templates including authorization and content-type. + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Entitlement Checks (_shared/entitlement.ts) +Responsibilities: +- Determine whether a user has access to AI features based on subscription status or feature flags. +- Cache results where appropriate to reduce overhead. +- Return clear allow/deny decisions to the proxy function. + +Integration: +- Called early in the proxy flow to gate access. +- Returns specific codes for billing-related denials. + +**Section sources** +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Frontend Integration Examples +- AiAssistant.jsx: Demonstrates invoking the AI proxy for conversational coaching and displaying incremental responses. +- MockInterviewPage.jsx: Shows batched prompting for mock interviews and result rendering. +- auth.jsx: Ensures user sessions are active before calling AI features. + +Best practices: +- Always pass user_id from the authenticated session. +- Show loading states and progress indicators during long-running operations. +- Handle network failures gracefully with user-friendly messages. + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [auth.jsx](file://src/auth.jsx) + +## Dependency Analysis +The AI proxy depends on shared modules for HTTP and entitlements, and the frontend depends on the client library. + +```mermaid +graph LR +FE["Frontend Components"] --> CL["ai.js"] +CL --> PROXY["ai-proxy/index.ts"] +PROXY --> HTTP["_shared/http.ts"] +PROXY --> ENT["_shared/entitlement.ts"] +PROXY --> EXT["External AI Service"] +``` + +**Diagram sources** +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Performance Considerations +- Use streaming for long responses to improve perceived latency. +- Set sensible timeouts to fail fast on slow providers. +- Cache entitlement checks to reduce repeated database lookups. +- Limit prompt sizes and apply token budgets to control costs. +- Implement circuit breakers around provider calls to avoid cascading failures. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid input: Ensure required fields are present and within allowed ranges. +- Unauthorized: Verify Supabase session and that the user is logged in. +- Forbidden: Confirm entitlements are active for AI features. +- Rate limited: Back off and retry after the suggested interval. +- Provider error: Inspect normalized error codes and messages without exposing secrets. + +Debugging tips: +- Enable detailed logs in development only. +- Correlate request IDs across frontend and backend. +- Validate environment variables for provider credentials. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Conclusion +The AI proxy function centralizes secure access to external AI services, enforcing authentication, entitlements, input validation, and rate limiting. It normalizes responses and supports streaming, providing a robust foundation for resume analysis and interview coaching features. By following the recommended patterns for client integration, retries, and security, teams can deliver reliable and cost-effective AI experiences. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### API Endpoint Reference +- Endpoint: POST /functions/v1/ai-proxy +- Authentication: Supabase session required +- Request body: + - user_id: string (required) + - prompt: string (required) + - options: object (optional) + - model: string + - temperature: number + - max_tokens: number + - top_p: number +- Response body: + - success: boolean + - data: object|string (normalized output or stream chunks) + - error: object|null (error code, message, details) +- Status codes: + - 200: Success + - 400: Invalid input + - 401: Unauthorized + - 403: Forbidden (no entitlement) + - 429: Rate limited + - 500: Internal error + - 502/503: Provider unavailable + +[No sources needed since this section provides general guidance] + +### Security Checklist +- Store AI provider credentials in environment variables only. +- Never accept secrets from clients. +- Validate and sanitize all inputs. +- Apply rate limiting per user and globally. +- Log minimal sensitive information. +- Use HTTPS and short-lived tokens where possible. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Billing & Payment Functions.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Billing & Payment Functions.md new file mode 100644 index 0000000..e4fa21a --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Billing & Payment Functions.md @@ -0,0 +1,464 @@ +# Billing & Payment Functions + + +**Referenced Files in This Document** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the billing and payment processing functions for initiating subscription payments, managing subscriptions, and handling webhooks from PayMongo and PayPal. It covers: +- Creating a checkout session to start a subscription payment (PayMongo and PayPal flows) +- Canceling an active subscription +- Webhook signature verification and idempotency +- Authentication requirements and error scenarios +- Frontend integration patterns for initiating checkouts and synchronizing subscription state + +## Project Structure +The billing system is implemented as Supabase Edge Functions with shared utilities and client-side helpers: +- Client helper: src/lib/billing.js +- Server endpoints: + - supabase/functions/create-checkout/index.ts + - supabase/functions/cancel-subscription/index.ts + - supabase/functions/paymongo-webhook/index.ts + - supabase/functions/paypal-webhook/index.ts + - supabase/functions/create-paypal-order/index.ts + - supabase/functions/capture-paypal-order/index.ts +- Shared libraries: + - supabase/functions/_shared/paypal.ts + - supabase/functions/_shared/paypal-runtime.ts + - supabase/functions/_shared/entitlement.ts + - supabase/functions/_shared/http.ts +- Design reference: docs/superpowers/plans/monetization/03-subscriptions-paymongo.md + +```mermaid +graph TB +FE["Frontend App
src/lib/billing.js"] --> CC["Create Checkout
supabase/functions/create-checkout/index.ts"] +FE --> CS["Cancel Subscription
supabase/functions/cancel-subscription/index.ts"] +CC --> PMW["PayMongo Webhook
supabase/functions/paymongo-webhook/index.ts"] +CC --> PPW["PayPal Webhook
supabase/functions/paypal-webhook/index.ts"] +CC --> CPO["Create PayPal Order
supabase/functions/create-paypal-order/index.ts"] +CPO --> CAP["Capture PayPal Order
supabase/functions/capture-paypal-order/index.ts"] +subgraph "Shared" +ENT["Entitlements
_shared/entitlement.ts"] +HTTP["HTTP Helpers
_shared/http.ts"] +PPT["PayPal SDK Wrapper
_shared/paypal.ts"] +PPR["PayPal Runtime Config
_shared/paypal-runtime.ts"] +end +CC --> ENT +CC --> HTTP +CPO --> PPT +CAP --> PPT +PPT --> PPR +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Create Checkout: Creates a PayMongo checkout session or a PayPal order for subscription payments. Returns a redirect URL or order ID for the frontend to complete payment. +- Cancel Subscription: Cancels an existing subscription based on provider-specific identifiers. +- Webhooks: + - PayMongo Webhook: Verifies signatures, validates events, updates entitlements, and ensures idempotent fulfillment. + - PayPal Webhook: Verifies webhook requests, decodes events, fulfills orders, and reconciles subscription state. +- Shared Utilities: + - Entitlements: Centralized logic to grant/revoke features based on subscription status. + - HTTP: Standardized outbound request helpers used by providers. + - PayPal SDK wrapper and runtime configuration for secure API calls. + +Key responsibilities: +- Enforce authentication before creating or modifying subscriptions. +- Validate and sign-check all incoming webhooks. +- Maintain idempotency using provider IDs and server-side deduplication. +- Keep client and server subscription state synchronized via webhooks and polling. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Architecture Overview +End-to-end flows: +- Initiate checkout: Frontend calls create-checkout; server returns a payment link or order ID; frontend redirects or completes payment. +- Fulfillment: Provider sends webhook; server verifies signature, checks idempotency, updates entitlements, and responds with success. +- Cancellation: Frontend calls cancel-subscription; server updates provider and local state. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant CC as "Create Checkout" +participant PM as "PayMongo" +participant PP as "PayPal" +participant PW as "PayMongo Webhook" +participant PPW as "PayPal Webhook" +participant ENT as "Entitlements" +FE->>CC : "Initiate subscription checkout" +alt "PayMongo flow" +CC->>PM : "Create checkout session" +PM-->>CC : "Checkout URL" +CC-->>FE : "Redirect URL" +PM-->>PW : "Payment event" +PW->>ENT : "Grant entitlements" +else "PayPal flow" +CC->>PP : "Create order" +PP-->>CC : "Order ID" +CC-->>FE : "Order ID" +PP-->>PPW : "Payment captured" +PPW->>ENT : "Grant entitlements" +end +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Create Checkout Function +Purpose: +- Start a subscription payment via PayMongo or PayPal. +- Accept user identity and plan details. +- Return a redirect URL (PayMongo) or order ID (PayPal). + +Request parameters: +- User identifier (authenticated context). +- Plan identifier or pricing metadata. +- Optional currency and region settings. +- Idempotency key (recommended for retries). + +Response formats: +- PayMongo: Redirect URL to complete checkout. +- PayPal: Order ID to be used by the frontend to finalize payment. + +Integration notes: +- Uses shared HTTP helpers for provider calls. +- For PayPal, may delegate to create-paypal-order and capture-paypal-order flows. +- Stores minimal metadata needed for reconciliation. + +Frontend usage pattern: +- Call create-checkout with plan and idempotency key. +- If PayMongo, redirect user to returned URL. +- If PayPal, use returned order ID to complete payment via PayPal UI. +- After completion, poll or listen for webhook-driven state changes. + +Error scenarios: +- Invalid or missing plan. +- Provider errors (network, auth, rate limits). +- Duplicate idempotency keys handled idempotently. + +Idempotency: +- Use a unique idempotency key per checkout attempt to prevent duplicate charges. + +Authentication: +- Requires authenticated user context before creating checkout. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +#### Create Checkout Flow (Sequence) +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant CC as "Create Checkout" +participant PM as "PayMongo" +participant PP as "PayPal" +FE->>CC : "POST /create-checkout {plan, idempotency_key}" +alt "PayMongo" +CC->>PM : "Create checkout session" +PM-->>CC : "checkout_url" +CC-->>FE : "{redirect_url}" +else "PayPal" +CC->>PP : "Create order" +PP-->>CC : "order_id" +CC-->>FE : "{order_id}" +end +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) + +### Cancel Subscription Function +Purpose: +- Cancel an active subscription for the authenticated user. +- Update provider and local state accordingly. + +Request parameters: +- Subscription identifier or provider-specific subscription ID. +- Reason (optional). + +Response format: +- Confirmation of cancellation with updated status. + +Lifecycle considerations: +- Ensure cancellation is idempotent. +- Handle partial failures gracefully and retry safely. +- Revoke entitlements after successful cancellation. + +Authentication: +- Requires authenticated user context and ownership validation. + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### PayMongo Webhook Handler +Responsibilities: +- Verify webhook signature using provider secret. +- Parse event payload and validate required fields. +- Check idempotency to avoid duplicate fulfillment. +- Update entitlements and return success response. + +Signature verification: +- Validate timestamp and signature headers against configured secret. + +Idempotency: +- Deduplicate events using event ID or transaction ID. + +State synchronization: +- On success, grant entitlements and persist subscription state. + +Error handling: +- Return appropriate HTTP status codes for invalid signatures or malformed payloads. +- Log detailed errors for observability. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +#### PayMongo Webhook Verification Flow (Flowchart) +```mermaid +flowchart TD +Start(["Receive Webhook"]) --> VerifySig["Verify Signature"] +VerifySig --> SigValid{"Signature Valid?"} +SigValid --> |No| Reject["Reject Request"] +SigValid --> |Yes| Parse["Parse Event Payload"] +Parse --> ValidateFields["Validate Required Fields"] +ValidateFields --> FieldsOK{"Fields Valid?"} +FieldsOK --> |No| Reject +FieldsOK --> |Yes| CheckDup["Check Idempotency Key"] +CheckDup --> IsDup{"Duplicate Event?"} +IsDup --> |Yes| AckDup["Acknowledge Existing Fulfillment"] +IsDup --> |No| Fulfill["Update Entitlements"] +Fulfill --> Success["Return Success"] +AckDup --> Success +Reject --> End(["End"]) +Success --> End +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### PayPal Webhook Handler +Responsibilities: +- Verify webhook authenticity and decode event. +- Map PayPal events to internal subscription states. +- Fulfill orders and update entitlements. +- Ensure idempotent processing using order/event IDs. + +Signature verification: +- Validate webhook headers and payload integrity. + +Idempotency: +- Track processed order/event IDs to prevent double fulfillment. + +State synchronization: +- On capture or approved events, grant entitlements and record subscription details. + +Error handling: +- Return proper responses for invalid requests and log actionable errors. + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +#### PayPal Webhook Processing Flow (Sequence) +```mermaid +sequenceDiagram +participant PP as "PayPal" +participant PPW as "PayPal Webhook" +participant ENT as "Entitlements" +PP->>PPW : "Webhook event (capture/approved)" +PPW->>PPW : "Verify signature and decode" +PPW->>PPW : "Check idempotency" +alt "New event" +PPW->>ENT : "Grant entitlements" +ENT-->>PPW : "Success" +PPW-->>PP : "200 OK" +else "Duplicate event" +PPW-->>PP : "200 OK (no-op)" +end +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Shared Utilities +- Entitlements: Centralized logic to manage feature access based on subscription status. Used by both webhooks and cancellation flows. +- HTTP: Standardized outbound requests to external services with retries and timeouts. +- PayPal SDK wrapper: Encapsulates PayPal API interactions and token management. +- PayPal runtime config: Loads environment variables securely at runtime. + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Dependency Analysis +High-level dependencies: +- create-checkout depends on HTTP helpers and provider APIs (PayMongo/PayPal). +- Webhooks depend on signature verification, idempotency checks, and entitlement updates. +- PayPal flows depend on PayPal SDK wrapper and runtime configuration. + +```mermaid +graph LR +CC["Create Checkout"] --> HTTP["HTTP Helpers"] +CC --> PM["PayMongo API"] +CC --> PP["PayPal API"] +PMW["PayMongo Webhook"] --> ENT["Entitlements"] +PPW["PayPal Webhook"] --> ENT +CPO["Create PayPal Order"] --> PPT["PayPal SDK Wrapper"] +CAP["Capture PayPal Order"] --> PPT +PPT --> PPR["PayPal Runtime Config"] +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Performance Considerations +- Minimize network calls by batching operations where possible. +- Use idempotency keys to avoid redundant provider requests. +- Implement short-lived retries with exponential backoff for transient errors. +- Cache non-sensitive configuration at runtime to reduce overhead. +- Keep webhook handlers fast and deterministic; offload heavy work if necessary. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid webhook signature: Ensure secrets are correctly configured and timestamps are within tolerance. +- Duplicate events: Confirm idempotency keys are present and persisted; verify deduplication logic. +- Missing plan or user context: Validate request payloads and ensure authentication middleware is applied. +- Provider errors: Inspect logs for network timeouts, rate limits, or invalid credentials. +- State drift: Reconcile subscription state by re-fetching provider data and updating entitlements. + +Operational tips: +- Log structured events with correlation IDs for tracing across components. +- Monitor webhook delivery and retry policies. +- Use test modes for PayMongo and PayPal during development. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) + +## Conclusion +The billing system provides robust subscription lifecycle management through well-defined serverless endpoints and secure webhook handlers. By enforcing authentication, verifying signatures, and implementing idempotency, the system ensures reliable payment processing and consistent entitlements across PayMongo and PayPal integrations. The frontend should initiate checkouts via the provided helper, handle provider redirects or order completions, and synchronize state using webhooks and periodic polling. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Frontend Integration Patterns +- Initiating checkout: + - Call create-checkout with plan and idempotency key. + - For PayMongo, redirect to returned URL. + - For PayPal, use returned order ID to complete payment. +- Handling callbacks: + - Listen for success/failure signals from provider UI. + - Poll server for subscription status until webhook confirms state. +- Synchronizing state: + - Query current subscription status from server. + - Update UI based on entitlements granted. + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Reference Documentation +- PayMongo subscription architecture and implementation details are documented in the monetization plans. + +**Section sources** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Edge Functions.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Edge Functions.md new file mode 100644 index 0000000..b75328e --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Edge Functions.md @@ -0,0 +1,547 @@ +# Edge Functions + + +**Referenced Files in This Document** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [functions config.toml](file://supabase/config.toml) +- [billing.js](file://src/lib/billing.js) +- [cloud.js](file://src/lib/cloud.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the Supabase Edge Functions for ApplyGuard PH, focusing on: +- AI proxy for resume analysis and interview coaching +- Billing functions for PayMongo and PayPal integrations +- Webhook handlers for payment processing +- Utility function for data export +It also covers authentication requirements, request/response formats, error handling patterns, security considerations, rate limiting, performance optimization, and frontend integration examples. + +## Project Structure +The Edge Functions are organized by feature under supabase/functions, with shared utilities under _shared. The configuration is defined in supabase/config.toml. Frontend libraries for calling these functions live in src/lib. + +```mermaid +graph TB +subgraph "Edge Functions" +A["ai-proxy/index.ts"] +B["create-checkout/index.ts"] +C["paymongo-webhook/index.ts"] +D["paypal-webhook/index.ts"] +E["capture-paypal-order/index.ts"] +F["create-paypal-order/index.ts"] +G["cancel-subscription/index.ts"] +H["download-message-pack/index.ts"] +S1["_shared/http.ts"] +S2["_shared/entitlement.ts"] +S3["_shared/paypal-runtime.ts"] +S4["_shared/paypal.ts"] +S5["_shared/prompts.ts"] +end +subgraph "Frontend Libraries" +L1["billing.js"] +L2["cloud.js"] +end +A --> S1 +A --> S5 +B --> S1 +C --> S1 +D --> S1 +E --> S3 +E --> S4 +F --> S3 +F --> S4 +G --> S2 +H --> S1 +L1 --> B +L1 --> C +L1 --> D +L1 --> E +L1 --> F +L1 --> G +L2 --> A +L2 --> H +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [billing.js](file://src/lib/billing.js) +- [cloud.js](file://src/lib/cloud.js) + +**Section sources** +- [functions config.toml](file://supabase/config.toml) +- [billing.js](file://src/lib/billing.js) +- [cloud.js](file://src/lib/cloud.js) + +## Core Components +- AI Proxy: Proxies requests to an external AI service for resume analysis and interview coaching. It validates inputs, enforces entitlements, and returns structured results. +- Checkout Creation: Creates a checkout session via PayMongo and returns a redirect URL or client-side token. +- PayMongo Webhook: Verifies webhook signatures, updates subscription status, and records fulfillment events. +- PayPal Webhooks: Handles order capture and subscription lifecycle events; fulfills entitlements accordingly. +- PayPal Order Management: Creates and captures PayPal orders, coordinating with billing state. +- Subscription Cancellation: Cancels subscriptions through provider APIs and updates local state. +- Data Export: Generates downloadable exports (e.g., message pack) for user data. + +Authentication and Authorization +- Protected endpoints require a valid Supabase session token passed as a header. +- Entitlement checks gate access to premium features (e.g., AI usage). +- Webhook endpoints validate provider signatures and enforce idempotency. + +Request/Response Patterns +- JSON payloads for most endpoints. +- Redirect URLs returned for checkout flows. +- Webhooks receive provider-specific payloads and return HTTP 2xx upon success. + +Security Considerations +- Validate and sanitize all inputs. +- Verify webhook signatures before processing. +- Use environment variables for secrets. +- Enforce least privilege when accessing databases or storage. + +Rate Limiting and Performance +- Implement per-user and global rate limits at the function level. +- Cache expensive computations where appropriate. +- Stream large responses when possible. + +Error Handling +- Return consistent error shapes with codes and messages. +- Log errors with correlation IDs. +- Avoid leaking sensitive details in responses. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Architecture Overview +High-level flow across components: +- Frontend calls create-checkout to initiate PayMongo checkout. +- Provider webhooks notify paymongo-webhook and paypal-webhook to update state. +- PayPal order creation and capture are handled by dedicated functions. +- AI proxy routes prompts to the AI backend after entitlement validation. +- Data export utility generates downloadable artifacts. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant CC as "create-checkout" +participant PMW as "paymongo-webhook" +participant PW as "paypal-webhook" +participant CO as "create-paypal-order" +participant CP as "capture-paypal-order" +participant AI as "ai-proxy" +participant DL as "download-message-pack" +FE->>CC : "POST /create-checkout {planId, userId}" +CC-->>FE : "{checkoutUrl}" +Note over CC,PMW : "PayMongo redirects user and sends webhook" +PMW-->>FE : "Async state update" +FE->>CO : "POST /create-paypal-order {planId, userId}" +CO-->>FE : "{orderId}" +FE->>CP : "POST /capture-paypal-order {orderId}" +CP-->>FE : "{status}" +PW-->>FE : "Async state update" +FE->>AI : "POST /ai-proxy {prompt, metadata}" +AI-->>FE : "{analysis, suggestions}" +FE->>DL : "GET /download-message-pack {filters}" +DL-->>FE : "File download" +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) + +## Detailed Component Analysis + +### AI Proxy +Purpose +- Validates user entitlements and forwards prompts to the AI backend for resume analysis and interview coaching. +- Returns structured results including scores, feedback, and suggested improvements. + +Endpoints +- POST /ai-proxy + +Request +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: prompt, context (optional), model (optional) + +Response +- Success: { result, tokens_used, plan } +- Error: { code, message } + +Authentication +- Requires a valid Supabase session token. + +Security +- Input validation and length limits. +- Prompt sanitization. +- Rate limiting per user. + +Performance +- Streaming responses for long outputs. +- Caching repeated prompts if applicable. + +Frontend Example +- See [cloud.js](file://src/lib/cloud.js) for how to call the AI proxy from the frontend. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [cloud.js](file://src/lib/cloud.js) + +### Create Checkout (PayMongo) +Purpose +- Initiates a PayMongo checkout session for a selected plan. + +Endpoints +- POST /create-checkout + +Request +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: planId, userId, returnUrl (optional) + +Response +- Success: { checkoutUrl } +- Error: { code, message } + +Authentication +- Requires a valid Supabase session token. + +Security +- Validate planId against allowed plans. +- Ensure userId matches authenticated user. + +Frontend Example +- See [billing.js](file://src/lib/billing.js) for creating checkouts and handling redirects. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [billing.js](file://src/lib/billing.js) + +### PayMongo Webhook +Purpose +- Receives PayMongo events, verifies signatures, and updates subscription status and entitlements. + +Endpoints +- POST /paymongo-webhook + +Request +- Headers: X-PayMongo-Signature +- Body: PayMongo event payload + +Response +- Success: HTTP 200 +- Failure: HTTP 400/500 with error details + +Security +- Signature verification. +- Idempotency checks using event IDs. + +Processing Logic +- Map events to subscription states. +- Record fulfillment events. +- Update entitlements. + +Frontend Impact +- No direct call; state changes propagate to the UI. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal Webhook +Purpose +- Processes PayPal order and subscription events, fulfilling entitlements and updating state. + +Endpoints +- POST /paypal-webhook + +Request +- Headers: Authorization (Bearer token for internal verification if required), Content-Type: application/json +- Body: PayPal event payload + +Response +- Success: HTTP 200 +- Failure: HTTP 400/500 with error details + +Security +- Verify webhook signature and event type. +- Idempotency checks. + +Processing Logic +- Handle order capture and subscription lifecycle events. +- Fulfill entitlements based on successful payments. + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Create PayPal Order +Purpose +- Creates a PayPal order for a selected plan. + +Endpoints +- POST /create-paypal-order + +Request +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: planId, userId, currency (optional) + +Response +- Success: { orderId } +- Error: { code, message } + +Authentication +- Requires a valid Supabase session token. + +Security +- Validate planId and currency. +- Ensure userId matches authenticated user. + +Frontend Example +- See [billing.js](file://src/lib/billing.js) for order creation flow. + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [billing.js](file://src/lib/billing.js) + +### Capture PayPal Order +Purpose +- Captures a previously created PayPal order and finalizes payment. + +Endpoints +- POST /capture-paypal-order + +Request +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: orderId + +Response +- Success: { status } +- Error: { code, message } + +Authentication +- Requires a valid Supabase session token. + +Security +- Validate orderId ownership. +- Prevent duplicate captures. + +Frontend Example +- See [billing.js](file://src/lib/billing.js) for capturing orders. + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [billing.js](file://src/lib/billing.js) + +### Cancel Subscription +Purpose +- Cancels a subscription via provider APIs and updates local state. + +Endpoints +- POST /cancel-subscription + +Request +- Headers: Authorization (Bearer token), Content-Type: application/json +- Body fields: subscriptionId, reason (optional) + +Response +- Success: { canceled } +- Error: { code, message } + +Authentication +- Requires a valid Supabase session token. + +Security +- Validate subscriptionId ownership. +- Ensure cancellation policy compliance. + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Download Message Pack +Purpose +- Exports user data as a downloadable message pack file. + +Endpoints +- GET /download-message-pack + +Request +- Headers: Authorization (Bearer token) +- Query parameters: filters (optional) + +Response +- Success: File download stream +- Error: { code, message } + +Authentication +- Requires a valid Supabase session token. + +Security +- Validate filters to prevent excessive queries. +- Respect user data permissions. + +Frontend Example +- See [cloud.js](file://src/lib/cloud.js) for initiating downloads. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) + +## Dependency Analysis +Shared utilities provide common functionality across functions: +- http.ts: Standardized HTTP helpers for requests and responses. +- entitlement.ts: Entitlement checks and management. +- paypal-runtime.ts and paypal.ts: PayPal SDK wrappers and runtime configuration. +- prompts.ts: Shared prompt templates and validation. + +```mermaid +classDiagram +class HttpHelpers { ++request(url, options) ++response(status, body) +} +class EntitlementService { ++check(userId, feature) bool ++grant(userId, feature) void ++revoke(userId, feature) void +} +class PayPalRuntime { ++configure(clientId, secret) ++getAccessToken() string +} +class PayPalApi { ++createOrder(planId, amount, currency) ++captureOrder(orderId) +} +class Prompts { ++validate(prompt) ++buildResumeAnalysisPrompt(context) +} +ai_proxy_index_ts --> HttpHelpers : "uses" +ai_proxy_index_ts --> Prompts : "uses" +create_checkout_index_ts --> HttpHelpers : "uses" +paymongo_webhook_index_ts --> HttpHelpers : "uses" +paypal_webhook_index_ts --> HttpHelpers : "uses" +create_paypal_order_index_ts --> PayPalRuntime : "uses" +create_paypal_order_index_ts --> PayPalApi : "uses" +capture_paypal_order_index_ts --> PayPalRuntime : "uses" +capture_paypal_order_index_ts --> PayPalApi : "uses" +cancel_subscription_index_ts --> EntitlementService : "uses" +download_message_pack_index_ts --> HttpHelpers : "uses" +``` + +**Diagram sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Performance Considerations +- Minimize cold starts by keeping dependencies lean. +- Use streaming for large exports and AI responses. +- Cache frequently accessed configuration and prompts. +- Batch database operations where possible. +- Implement retry logic with exponential backoff for external API calls. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common Issues +- Authentication failures: Ensure Authorization header contains a valid Supabase token. +- Webhook signature mismatches: Verify provider signatures and environment variables. +- Duplicate webhook processing: Confirm idempotency keys are used and checked. +- Rate limit exceeded: Check per-user quotas and adjust thresholds. + +Debugging Tips +- Enable detailed logging with correlation IDs. +- Inspect request payloads and response bodies. +- Validate environment variables for provider credentials. + +**Section sources** +- [_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +## Conclusion +ApplyGuard PH’s Edge Functions provide a secure, scalable foundation for AI-powered resume analysis and interview coaching, robust billing integrations with PayMongo and PayPal, and reliable data export capabilities. By following the authentication, security, and performance guidelines outlined here, developers can integrate these functions confidently into the frontend and maintain high reliability and user experience. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Frontend Integration Examples +- Calling AI Proxy: Refer to [cloud.js](file://src/lib/cloud.js) for example usage. +- Creating PayMongo Checkout: Refer to [billing.js](file://src/lib/billing.js) for checkout initiation and redirect handling. +- Managing PayPal Orders: Refer to [billing.js](file://src/lib/billing.js) for order creation and capture flows. +- Downloading Data: Refer to [cloud.js](file://src/lib/cloud.js) for initiating downloads. + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) +- [billing.js](file://src/lib/billing.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/PayMongo Webhook Handler.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/PayMongo Webhook Handler.md new file mode 100644 index 0000000..85dc69b --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/PayMongo Webhook Handler.md @@ -0,0 +1,383 @@ +# PayMongo Webhook Handler + + +**Referenced Files in This Document** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [003-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive documentation for the PayMongo webhook handler responsible for receiving and processing payment events from PayMongo. It covers the webhook endpoint, supported event types (payment completed, failed, refunded), request validation using webhook signatures, event processing logic, subscription status updates in the database, duplicate handling, retry mechanisms, payload examples, error handling strategies, debugging techniques, and security considerations including IP whitelisting and signature verification. + +## Project Structure +The PayMongo webhook handler is implemented as a Supabase Edge Function under supabase/functions/paymongo-webhook/index.ts. Shared utilities for HTTP handling and entitlements are located under supabase/functions/_shared/. The monetization plan documents provide additional context on subscription flows and integration points. + +```mermaid +graph TB +subgraph "Supabase Functions" +PMW["paymongo-webhook/index.ts"] +SH_HTTP["_shared/http.ts"] +SH_ENT["_shared/entitlement.ts"] +end +subgraph "External Services" +PAYMONGO["PayMongo API"] +DB["Supabase Database"] +end +PAYMONGO --> PMW +PMW --> SH_HTTP +PMW --> SH_ENT +PMW --> DB +``` + +**Diagram sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [003-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Webhook Endpoint: Receives POST requests from PayMongo with signed payloads. +- Signature Verification: Validates the webhook signature to ensure authenticity. +- Event Routing: Dispatches events based on type (e.g., payment completed, failed, refunded). +- Subscription Updates: Persists state changes to the database via shared entitlement utilities. +- Idempotency and Deduplication: Prevents reprocessing of duplicate webhooks. +- Retry Strategy: Implements retries for transient failures during processing. + +Key responsibilities: +- Parse and validate incoming requests. +- Verify webhook signature securely. +- Normalize event data into internal representations. +- Update subscription status deterministically. +- Ensure idempotent operations. +- Log actionable diagnostics for troubleshooting. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview +The webhook handler follows a layered approach: +- Ingress layer validates HTTP method and content type. +- Security layer verifies the PayMongo signature using configured secrets. +- Processing layer routes events by type and applies business rules. +- Persistence layer updates subscription records and related entities. +- Observability layer logs structured events and errors. + +```mermaid +sequenceDiagram +participant Client as "PayMongo" +participant Func as "paymongo-webhook/index.ts" +participant Http as "_shared/http.ts" +participant Ent as "_shared/entitlement.ts" +participant DB as "Supabase Database" +Client->>Func : "POST /functions/v1/paymongo-webhook"
Headers : "X-PayMongo-Signature", "Content-Type : application/json" +Func->>Http : "Validate request shape and headers" +Func->>Func : "Verify webhook signature" +alt "Signature valid" +Func->>Func : "Parse event payload" +Func->>Func : "Route by event type" +alt "Payment Completed" +Func->>Ent : "Update subscription to active" +Ent->>DB : "Upsert subscription record" +DB-->>Ent : "OK" +Ent-->>Func : "Success" +else "Payment Failed" +Func->>Ent : "Mark subscription as failed" +Ent->>DB : "Upsert subscription record" +DB-->>Ent : "OK" +Ent-->>Func : "Success" +else "Refunded" +Func->>Ent : "Adjust subscription/refund state" +Ent->>DB : "Upsert subscription record" +DB-->>Ent : "OK" +Ent-->>Func : "Success" +end +Func-->>Client : "200 OK" +else "Signature invalid" +Func-->>Client : "401 Unauthorized" +end +``` + +**Diagram sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Webhook Endpoint and Request Validation +- Accepts only POST requests with JSON payloads. +- Requires specific headers for signature verification. +- Returns appropriate HTTP status codes for malformed or unauthorized requests. + +Validation steps: +- Check HTTP method and content type. +- Extract signature header and payload body. +- Compute expected signature using shared HTTP utilities and secret configuration. +- Compare signatures securely. + +Security considerations: +- Use environment variables for secrets; never hardcode. +- Reject requests without required headers. +- Return minimal information on failure to avoid leaking internals. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Supported Event Types +- Payment Completed: Transition subscription to active and grant entitlements. +- Payment Failed: Mark subscription as failed and optionally notify users. +- Refunded: Adjust subscription state and handle refund-related side effects. + +Processing logic: +- Map external event fields to internal models. +- Apply deterministic state transitions. +- Record audit entries for traceability. + +Idempotency: +- Use event IDs to detect duplicates. +- Skip processing if already handled. +- Maintain a deduplication store or rely on database constraints. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Subscription Status Updates +- Uses shared entitlement utilities to update subscription records. +- Ensures atomic updates with consistent state transitions. +- Handles edge cases such as concurrent updates and partial failures. + +Database interactions: +- Upsert subscription rows with new status and timestamps. +- Enforce constraints to prevent inconsistent states. +- Optionally log change history for auditing. + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Duplicate Handling and Retry Mechanisms +Duplicate handling: +- Track processed event IDs to avoid reprocessing. +- Leverage database unique constraints for robustness. +- Return success immediately for known duplicates. + +Retry strategy: +- Implement exponential backoff for transient errors (network timeouts, database locks). +- Limit maximum retries to prevent infinite loops. +- Queue failed events for later processing if necessary. + +Operational notes: +- Distinguish between retriable and non-retriable errors. +- Surface actionable errors to observability systems. +- Avoid retrying on invalid signatures or malformed payloads. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Payload Examples +Below are conceptual examples of webhook payloads for each event type. Replace placeholders with actual values when testing. + +- Payment Completed + - Fields: event_id, event_type, payment_id, amount, currency, customer_id, metadata.subscription_id, status + - Example structure: + { + "event_id": "evt_abc123", + "event_type": "payment.completed", + "payment_id": "pay_xyz789", + "amount": 1000, + "currency": "PHP", + "customer_id": "cus_def456", + "metadata": { + "subscription_id": "sub_ghi012" + }, + "status": "completed" + } + +- Payment Failed + - Fields: event_id, event_type, payment_id, amount, currency, customer_id, metadata.subscription_id, status, error_code + - Example structure: + { + "event_id": "evt_jkl345", + "event_type": "payment.failed", + "payment_id": "pay_mno678", + "amount": 1000, + "currency": "PHP", + "customer_id": "cus_def456", + "metadata": { + "subscription_id": "sub_ghi012" + }, + "status": "failed", + "error_code": "insufficient_funds" + } + +- Refunded + - Fields: event_id, event_type, payment_id, amount, currency, customer_id, metadata.subscription_id, status, refund_id + - Example structure: + { + "event_id": "evt_pqr901", + "event_type": "payment.refunded", + "payment_id": "pay_xyz789", + "amount": 1000, + "currency": "PHP", + "customer_id": "cus_def456", + "metadata": { + "subscription_id": "sub_ghi012" + }, + "status": "refunded", + "refund_id": "rfn_s234t5" + } + +Note: These examples illustrate typical fields used to identify and process events. Adapt to your schema and metadata conventions. + +[No sources needed since this section provides conceptual payload examples] + +### Error Handling Strategies +- Signature mismatch: Return 401 Unauthorized and log details. +- Malformed payload: Return 400 Bad Request and log parsing errors. +- Unknown event type: Return 200 OK with no-op processing and log warning. +- Transient failures: Retry with backoff and log retry attempts. +- Permanent failures: Record error state and alert operators. + +Best practices: +- Include correlation IDs for tracing across services. +- Avoid exposing sensitive details in responses. +- Aggregate metrics for error rates and latency. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Debugging Techniques +- Enable structured logging with event_id, payment_id, and subscription_id. +- Inspect raw payloads in safe environments for reproduction. +- Validate signature computation locally using test keys. +- Monitor database updates and transaction outcomes. +- Use feature flags to toggle verbose logging in staging. + +Common pitfalls: +- Time skew causing signature verification issues. +- Incorrect secret configuration. +- Missing headers or wrong content type. +- Race conditions leading to duplicate processing. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +### Security Considerations +IP Whitelisting: +- If enforced at the platform level, restrict inbound traffic to PayMongo IPs. +- Combine with signature verification for defense-in-depth. + +Signature Verification: +- Always verify the X-PayMongo-Signature header against the payload using the configured secret. +- Use constant-time comparison to prevent timing attacks. +- Reject requests lacking required headers. + +Secret Management: +- Store secrets in environment variables managed by the hosting platform. +- Rotate secrets periodically and invalidate old ones safely. + +Data Minimization: +- Log only necessary fields; redact sensitive data. +- Avoid storing full payloads beyond what is required for auditing. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Dependency Analysis +The webhook handler depends on shared utilities for HTTP handling and entitlement management. External dependencies include PayMongo’s API and the Supabase database. + +```mermaid +graph LR +PMW["paymongo-webhook/index.ts"] --> SH_HTTP["_shared/http.ts"] +PMW --> SH_ENT["_shared/entitlement.ts"] +PMW --> DB["Supabase Database"] +PMW --> PAYMONGO["PayMongo API"] +``` + +**Diagram sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Performance Considerations +- Keep processing lightweight; offload heavy tasks to background jobs if needed. +- Use database indexes on frequently queried fields (e.g., subscription_id, event_id). +- Batch updates where possible to reduce round trips. +- Cache static configuration to minimize overhead. +- Monitor latency and throughput; set alerts for anomalies. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Symptoms and resolutions: +- 401 Unauthorized on webhook calls: + - Verify signature header presence and correctness. + - Confirm secret configuration matches PayMongo settings. +- 400 Bad Request: + - Check content type and payload structure. + - Validate required fields and formats. +- No subscription updates: + - Inspect event routing and mapping logic. + - Review database constraints and transaction outcomes. +- Duplicate processing: + - Ensure event_id deduplication is enforced. + - Check for race conditions and implement locking if necessary. +- Retries not working: + - Validate backoff configuration and retry limits. + - Differentiate between retriable and non-retriable errors. + +Operational tips: +- Correlate logs using event_id and payment_id. +- Reproduce issues with test payloads in staging. +- Alert on elevated error rates and slow response times. + +**Section sources** +- [index.ts](file://supabase/functions/paymongo-webhook/index.ts) + +## Conclusion +The PayMongo webhook handler provides a secure, reliable, and extensible mechanism for processing payment events. By enforcing strict request validation, verifying signatures, implementing idempotent processing, and updating subscription statuses deterministically, it ensures consistency and resilience. Adhering to the recommended security practices, performance optimizations, and troubleshooting strategies will help maintain a robust integration. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Checklist +- Environment variables for secrets and endpoints. +- Feature flags for logging verbosity. +- Retry parameters (max attempts, backoff multiplier). +- Monitoring and alerting thresholds. + +### References +- Monetization plan for subscriptions and PayMongo integration. + +**Section sources** +- [003-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/PayPal Integration Functions.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/PayPal Integration Functions.md new file mode 100644 index 0000000..00578ca --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/PayPal Integration Functions.md @@ -0,0 +1,341 @@ +# PayPal Integration Functions + + +**Referenced Files in This Document** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the PayPal-specific integration functions used to initiate transactions, complete payments, and process events from PayPal. It covers: +- Creating a PayPal order from the frontend via a serverless function +- Capturing an approved order to finalize payment +- Handling PayPal webhooks for post-payment events (e.g., completed payments, refunds, disputes) +- OAuth authentication flow with PayPal +- Order management lifecycle and state reconciliation +- Webhook event types and payload validation +- Security measures including signature verification and idempotency + +## Project Structure +The PayPal integration is implemented as Supabase Edge Functions and shared utilities: +- create-paypal-order: Creates a PayPal order on behalf of the client +- capture-paypal-order: Captures an approved PayPal order +- paypal-webhook: Processes incoming PayPal webhook events +- _shared/paypal.ts and _shared/paypal-runtime.ts: Shared PayPal client logic and runtime configuration +- supabase/migrations/002_paypal_fulfillment.sql: Database schema for tracking fulfillment and order state + +```mermaid +graph TB +FE["Frontend App"] --> CO["Create PayPal Order Function"] +FE --> CAP["Capture PayPal Order Function"] +PP["PayPal API"] --> CO +PP --> CAP +PP --> WH["PayPal Webhook"] +WH --> PWH["PayPal Webhook Handler"] +DB[(Supabase DB)] --> PWH +DB --> CAP +CO --> DB +CAP --> DB +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Create PayPal Order Function: Accepts client request, authenticates with PayPal using OAuth, creates an order, persists order metadata, and returns the order ID and approval URL to the frontend. +- Capture PayPal Order Function: Validates that the order exists and is approved, calls PayPal to capture the order, updates fulfillment status, and returns confirmation. +- PayPal Webhook Handler: Receives PayPal events, validates signatures, normalizes payloads, performs idempotent processing, and reconciles order state in the database. +- Shared PayPal Client: Encapsulates OAuth token retrieval, HTTP calls to PayPal, error mapping, and retry/backoff strategies. +- Runtime Configuration: Loads environment variables such as client ID, secret, and webhook secrets; configures base URLs for sandbox vs production. + +Key responsibilities and interactions are detailed in the following sections. + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Architecture Overview +The system follows a standard e-commerce payment flow: +- Frontend initiates checkout by calling the create order function. +- Frontend redirects the user to PayPal for approval. +- After approval, the frontend calls the capture order function. +- PayPal sends asynchronous webhook events for post-capture lifecycle changes. +- The webhook handler updates internal records and triggers fulfillment. + +```mermaid +sequenceDiagram +participant FE as "Frontend" +participant CO as "Create Order Function" +participant PP as "PayPal API" +participant CAP as "Capture Order Function" +participant WH as "Webhook Handler" +participant DB as "Database" +FE->>CO : "Create order request" +CO->>PP : "OAuth token + Create Order" +PP-->>CO : "Order ID + Approval URL" +CO-->>FE : "Order ID + Approval URL" +FE->>PP : "User approves on PayPal" +FE->>CAP : "Capture order request" +CAP->>PP : "Capture Order" +PP-->>CAP : "Payment captured" +CAP->>DB : "Update fulfillment status" +PP->>WH : "Webhook event" +WH->>DB : "Idempotent update and reconciliation" +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Create PayPal Order Function +Purpose: +- Authenticate with PayPal using OAuth client credentials. +- Create a PayPal order with intent and purchase units. +- Persist order metadata (order ID, amount, currency, status). +- Return the order ID and approval URL to the frontend. + +Key behaviors: +- Uses shared PayPal client for OAuth and HTTP requests. +- Validates input parameters (amount, currency, items). +- Stores order state to enable later capture and reconciliation. +- Returns structured response suitable for frontend redirect. + +Frontend example usage: +- Call the create order endpoint with cart details. +- Use the returned approval URL to redirect the buyer to PayPal. +- On return, call the capture order endpoint with the order ID. + +Security considerations: +- Server-side only creation of orders; never expose secrets to the client. +- Validate amounts and currencies server-side. + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +### Capture PayPal Order Function +Purpose: +- Verify that the order exists and is approved. +- Request PayPal to capture the order. +- Update fulfillment status in the database. +- Return success or error to the frontend. + +Key behaviors: +- Checks order state before capture to prevent double-capture. +- Calls PayPal capture API using shared client. +- Persists capture result and timestamps. +- Handles partial captures or errors gracefully. + +Frontend example usage: +- After successful PayPal approval, call the capture endpoint with the order ID. +- Display confirmation and proceed with fulfillment. + +Security considerations: +- Ensure the caller is authorized to capture the specific order. +- Idempotently handle retries from the client. + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### PayPal Webhook Handler +Purpose: +- Receive and validate PayPal webhook events. +- Normalize payloads and route to handlers based on event type. +- Perform idempotent processing using event IDs. +- Reconcile order state and trigger fulfillment actions. + +Supported event types: +- Payment completion (e.g., capture completed) +- Refund events (partial/full) +- Dispute events (opened, resolved, lost/won) +- Order state transitions (approved, voided, expired) + +Payload validation: +- Verify webhook signature using provided headers and secret. +- Parse and validate JSON payload structure. +- Reject malformed or unverified events. + +Processing logic: +- Lookup order by PayPal order ID. +- Apply idempotency key (event ID) to avoid duplicate processing. +- Update fulfillment status and audit logs. +- Trigger downstream actions (e.g., grant entitlements, send notifications). + +```mermaid +flowchart TD +Start(["Receive Webhook"]) --> VerifySig["Verify Signature"] +VerifySig --> Valid{"Signature Valid?"} +Valid --> |No| Reject["Reject Event"] +Valid --> |Yes| Parse["Parse Payload"] +Parse --> Type{"Event Type"} +Type --> |Capture Completed| HandleCapture["Handle Capture"] +Type --> |Refund| HandleRefund["Handle Refund"] +Type --> |Dispute| HandleDispute["Handle Dispute"] +Type --> |Other| HandleOther["Handle Other Transitions"] +HandleCapture --> Idem["Check Idempotency Key"] +HandleRefund --> Idem +HandleDispute --> Idem +HandleOther --> Idem +Idem --> Exists{"Order Exists?"} +Exists --> |No| LogMissing["Log Missing Order"] +Exists --> |Yes| Update["Update Fulfillment Status"] +Update --> Done(["Return 200 OK"]) +LogMissing --> Done +Reject --> Done +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Shared PayPal Client and Runtime +Responsibilities: +- OAuth client credentials flow to obtain access tokens. +- HTTP wrappers for PayPal APIs with error handling and retries. +- Environment-based configuration for sandbox vs production endpoints. +- Utility functions for signing, timestamping, and header construction. + +Runtime configuration: +- Loads client ID, secret, and webhook secrets from environment. +- Selects appropriate base URLs for sandbox or live environments. +- Provides centralized logging and metrics hooks. + +Testing: +- Unit tests cover token retrieval, request formatting, and error paths. +- Mocks simulate PayPal responses for predictable test outcomes. + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +### Database Schema for Fulfillment +The migration defines tables and columns to track: +- PayPal order identifiers and amounts +- Internal order references and user associations +- Fulfillment status and timestamps +- Audit fields for reconciliation and debugging + +Key concepts: +- Unique constraints on PayPal order IDs to support idempotency. +- Status enums for clear state transitions. +- Indexes for efficient lookup during capture and webhook processing. + +**Section sources** +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +High-level dependencies: +- create-paypal-order depends on shared PayPal client and runtime configuration. +- capture-paypal-order depends on shared PayPal client, runtime configuration, and database schema. +- paypal-webhook depends on shared PayPal client, runtime configuration, and database schema. +- Tests depend on shared PayPal client for mocking and assertions. + +```mermaid +graph LR +CO["Create Order Function"] --> PC["Shared PayPal Client"] +CO --> RT["Runtime Config"] +CAP["Capture Order Function"] --> PC +CAP --> RT +WH["Webhook Handler"] --> PC +WH --> RT +DB["Fulfillment Schema"] --> CAP +DB --> WH +TESTS["Unit Tests"] --> PC +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Minimize network calls by caching PayPal access tokens where safe and supported. +- Use connection pooling and timeouts when calling PayPal APIs. +- Keep webhook handlers fast and idempotent; perform heavy work asynchronously if needed. +- Avoid redundant database writes; batch updates when possible. +- Monitor latency and error rates for PayPal API calls and adjust backoff/retry policies accordingly. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid signature on webhook: + - Ensure webhook secret is correctly configured and matches PayPal settings. + - Verify headers and payload integrity before verification. +- Double-capture or duplicate fulfillment: + - Confirm idempotency keys are enforced using event IDs and order states. + - Check database constraints and unique indexes. +- Order not found during capture: + - Validate that the order was created and persisted successfully. + - Inspect logs for missing or mismatched order IDs. +- Partial captures or refunds: + - Ensure handlers account for partial amounts and update balances accordingly. + - Reconcile totals against PayPal capture/refund records. +- Sandbox vs production misconfiguration: + - Confirm base URLs and credentials match the intended environment. + - Test end-to-end flows in sandbox before enabling live traffic. + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Conclusion +The PayPal integration implements a robust, secure, and idempotent flow for creating orders, capturing payments, and processing post-payment events. By centralizing OAuth and HTTP logic in a shared client, enforcing signature verification and idempotency in the webhook handler, and maintaining clear order state in the database, the system ensures reliable transaction processing and easy reconciliation. Follow the security best practices outlined here to protect sensitive operations and maintain consistency across all payment lifecycles. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Utility Functions.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Utility Functions.md new file mode 100644 index 0000000..b629dc0 --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Edge Functions/Utility Functions.md @@ -0,0 +1,285 @@ +# Utility Functions + + +**Referenced Files in This Document** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [generate_message_pack.py](file://scripts/generate_message_pack.py) +- [store.jsx](file://src/store.jsx) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the utility functions that support exporting application data as a MessagePack archive. It focuses on the server-side download endpoint, the client-side orchestration, and the frontend patterns for triggering downloads, handling large exports, and tracking progress. It also covers file format specifications, data structure, compression options, security measures, and best practices. + +## Project Structure +The export feature spans three layers: +- Serverless function to assemble and stream the MessagePack archive +- Client utilities to request and handle the download +- Frontend components to trigger exports and show progress + +```mermaid +graph TB +subgraph "Frontend" +UI["UI Components
e.g., Settings, Account Page"] +Store["Store (state)"] +CloudLib["Cloud Utilities"] +StorageLib["Local Storage Utilities"] +end +subgraph "Serverless Function" +MPFunc["Download Message Pack Function"] +end +subgraph "Data Sources" +Supabase["Supabase Database"] +end +UI --> Store +Store --> CloudLib +CloudLib --> MPFunc +MPFunc --> Supabase +CloudLib --> StorageLib +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +## Core Components +- Download Message Pack Function: Assembles exported data into a MessagePack archive and streams it back to the client with appropriate headers. +- Client Cloud Utilities: Call the serverless function, handle streaming responses, and manage local storage state for progress and status. +- Local Storage Utilities: Persist export state (progress, status, error messages) across sessions. +- CSV Utilities: Provide optional CSV-based exports as an alternative or complementary format. +- Share Utilities: Offer sharing mechanisms that may integrate with export flows. + +Key responsibilities: +- Data gathering and serialization into MessagePack +- Streaming response generation +- Progress reporting and error propagation +- File naming, MIME type, and content disposition + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) + +## Architecture Overview +The export flow is designed for reliability and scalability: +- The frontend requests an export via the serverless function. +- The function authenticates the user, gathers data from the database, serializes it into MessagePack, and streams the result. +- The client receives a streaming response, updates progress, and triggers the browser download when complete. + +```mermaid +sequenceDiagram +participant UI as "Frontend UI" +participant Store as "Store" +participant Cloud as "Cloud Utilities" +participant Func as "Download Message Pack Function" +participant DB as "Database" +UI->>Store : "Start export" +Store->>Cloud : "Request export" +Cloud->>Func : "POST /download-message-pack" +Func->>DB : "Query required datasets" +DB-->>Func : "Raw records" +Func->>Func : "Serialize to MessagePack" +Func-->>Cloud : "Streamed archive" +Cloud-->>Store : "Progress events" +Cloud-->>UI : "Download triggered" +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [store.jsx](file://src/store.jsx) + +## Detailed Component Analysis + +### Download Message Pack Function +Responsibilities: +- Authenticate and authorize the request using session context. +- Collect all relevant application data for the current user. +- Serialize data into a MessagePack archive. +- Stream the archive to the client with correct headers. +- Handle errors and return meaningful status codes. + +File format specification: +- Archive format: MessagePack (.msgpack) +- Content-Type: application/octet-stream +- Content-Disposition: attachment; filename="export.msgpack" + +Data structure: +- Top-level object containing named sections for each domain area (for example, users, interviews, offers, scans). +- Each section contains arrays of records with consistent field names and types. +- Timestamps are ISO strings; numeric fields use numbers; boolean fields use booleans. + +Compression options: +- Optional gzip compression can be applied before streaming if enabled by configuration. +- If compressed, set Content-Encoding: gzip and adjust filename accordingly. + +Security measures: +- Enforce user authentication and row-level access control. +- Validate and sanitize inputs. +- Rate-limit export requests per user. +- Avoid including sensitive fields unless explicitly permitted. + +Error handling: +- Return HTTP 401/403 for unauthorized access. +- Return HTTP 429 for rate limiting. +- Return HTTP 500 with structured error details for server failures. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) + +### Client Cloud Utilities +Responsibilities: +- Build authenticated requests to the serverless function. +- Handle streaming responses and parse progress events. +- Trigger browser download upon completion. +- Manage local storage state for progress and errors. + +Streaming behavior: +- Use ReadableStream to process chunks. +- Update progress based on total size and bytes received. +- Abort on network errors or cancellation. + +Progress tracking: +- Emit incremental progress updates to the store. +- Persist progress to local storage for resilience. + +Large file handling: +- Chunked processing to avoid memory spikes. +- Graceful retry on transient network issues. + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) + +### Local Storage Utilities +Responsibilities: +- Persist export state (status, progress, error message, timestamp). +- Provide getters/setters for export-related keys. +- Clean up stale entries after successful downloads. + +State schema: +- status: "idle" | "in_progress" | "completed" | "error" +- progress: number (0–100) +- error: string | null +- lastUpdated: timestamp + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### CSV Utilities +Responsibilities: +- Convert tabular data to CSV strings. +- Provide helpers for escaping and encoding. +- Support optional zipped CSV archives. + +Use cases: +- Alternative export format for compatibility. +- Preprocessing step before MessagePack assembly. + +**Section sources** +- [csv.js](file://src/lib/csv.js) + +### Share Utilities +Responsibilities: +- Generate shareable links or payloads. +- Integrate with export flows for quick sharing. + +Integration points: +- May reference exported artifacts or temporary URLs. + +**Section sources** +- [share.js](file://src/lib/share.js) + +### MessagePack Generation Script +Purpose: +- Provide a deterministic generator for sample MessagePack archives used in tests or demos. +- Ensure consistency between server serialization and client expectations. + +Usage: +- Run script to produce a .msgpack fixture. +- Compare fixtures against generated output during validation. + +**Section sources** +- [generate_message_pack.py](file://scripts/generate_message_pack.py) + +## Dependency Analysis +The export feature depends on: +- Authentication and authorization middleware within the serverless function runtime. +- Database queries scoped to the authenticated user. +- Client-side streaming libraries and local storage APIs. + +```mermaid +graph LR +UI["Frontend UI"] --> Store["Store"] +Store --> Cloud["Cloud Utilities"] +Cloud --> Func["Download Message Pack Function"] +Func --> DB["Database"] +Cloud --> Storage["Local Storage"] +``` + +**Diagram sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +## Performance Considerations +- Streaming: Prefer streaming over buffering entire archives in memory. +- Compression: Enable gzip for large exports to reduce bandwidth. +- Pagination: For very large datasets, consider paginated exports or segmented archives. +- Caching: Cache frequently accessed reference data to speed up serialization. +- Backpressure: Respect backpressure in streaming to prevent memory growth. +- Timeouts: Set reasonable timeouts and implement retries for long-running exports. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Unauthorized access: Verify session validity and permissions. +- Rate limiting: Implement exponential backoff and queueing. +- Large file timeouts: Switch to chunked downloads or segmented archives. +- Corrupted archives: Validate checksums and re-export if necessary. +- Progress not updating: Check streaming event parsing and local storage persistence. + +Operational checks: +- Confirm Content-Type and Content-Disposition headers. +- Validate MessagePack schema against expected structure. +- Inspect server logs for query performance bottlenecks. + +**Section sources** +- [download-message-pack/index.ts](file://supabase/functions/download-message-pack/index.ts) +- [cloud.js](file://src/lib/cloud.js) +- [storage.js](file://src/lib/storage.js) + +## Conclusion +The export utility provides a robust, secure, and scalable way to deliver application data as a MessagePack archive. By leveraging streaming, compression, and clear error handling, it supports both small and large exports while maintaining a responsive user experience. Follow the guidelines here to implement reliable downloads, track progress, and protect user data. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Backend Services (Supabase)/Shared Utilities Library.md b/.qoder/repowiki/en/content/Backend Services (Supabase)/Shared Utilities Library.md new file mode 100644 index 0000000..7927ef1 --- /dev/null +++ b/.qoder/repowiki/en/content/Backend Services (Supabase)/Shared Utilities Library.md @@ -0,0 +1,461 @@ +# Shared Utilities Library + + +**Referenced Files in This Document** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the shared utilities library used across Supabase Edge Functions for ApplyGuard PH. It focuses on: +- Entitlement system for feature access control +- HTTP client utilities for external API calls +- PayPal integration helpers and runtime configuration +- Prompt management for AI features +- Runtime configuration utilities + +It also explains common patterns, error handling strategies, logging approaches, testing methodologies, usage examples, best practices, and guidelines for extending the library. + +## Project Structure +The shared utilities live under supabase/functions/_shared and are consumed by multiple edge functions. The key modules are: +- entitlement.ts: Feature entitlement checks and caching +- http.ts: Typed HTTP client with retries and timeouts +- paypal.ts and paypal-runtime.ts: PayPal client and runtime configuration +- prompts.ts: Centralized prompt templates and resolution logic + +Edge functions that consume these utilities include: +- create-paypal-order/index.ts +- capture-paypal-order/index.ts +- paypal-webhook/index.ts +- ai-proxy/index.ts + +```mermaid +graph TB +subgraph "Shared Utilities" +ENT["entitlement.ts"] +HTTP["http.ts"] +PP["paypal.ts"] +PPR["paypal-runtime.ts"] +PROMPTS["prompts.ts"] +end +subgraph "Edge Functions" +CPO["create-paypal-order/index.ts"] +CPOr["capture-paypal-order/index.ts"] +PW["paypal-webhook/index.ts"] +AIP["ai-proxy/index.ts"] +end +CPO --> PP +CPO --> PPR +CPO --> ENT +CPO --> HTTP +CPOr --> PP +CPOr --> PPR +CPOr --> ENT +CPOr --> HTTP +PW --> PP +PW --> PPR +PW --> ENT +PW --> HTTP +AIP --> PROMPTS +AIP --> ENT +AIP --> HTTP +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Core Components +- Entitlements: Provides a consistent way to check whether a user has access to a feature, including caching and fallback behavior. +- HTTP Client: A typed wrapper around fetch with configurable timeouts, retries, and structured error responses. +- PayPal Helpers: Encapsulates PayPal order creation, capture, and webhook processing with environment-driven configuration. +- Prompts: Centralizes prompt templates and provides helpers to resolve and render prompts for AI features. +- Runtime Configuration: Supplies safe access to environment variables and defaults for edge functions. + +Common patterns: +- All public APIs return structured results with explicit success/failure states. +- Errors are normalized and logged consistently. +- External calls are wrapped with timeouts and retries where appropriate. +- Environment variables are validated at startup or first use. + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Architecture Overview +The shared utilities form a cohesive layer between edge functions and external services (PayPal, AI providers). They standardize: +- Authentication context propagation +- Feature gating via entitlements +- Reliable outbound networking +- Consistent prompt rendering for AI flows + +```mermaid +sequenceDiagram +participant EF as "Edge Function" +participant ENT as "Entitlements" +participant HTTP as "HTTP Client" +participant PP as "PayPal Helpers" +participant ENV as "Runtime Config" +EF->>ENV : "Load environment variables" +EF->>ENT : "Check feature access" +alt "Access granted" +EF->>PP : "Create PayPal order" +PP->>HTTP : "POST /v2/checkout/orders" +HTTP-->>PP : "Order response" +PP-->>EF : "Order details" +else "Access denied" +ENT-->>EF : "Deny with reason" +end +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) + +## Detailed Component Analysis + +### Entitlement System +Purpose: +- Gate access to premium features based on subscription status or other criteria. +- Provide caching to reduce repeated checks. +- Return deterministic, testable results. + +Key responsibilities: +- Resolve user identity and subscription state. +- Evaluate entitlement rules per feature. +- Cache results with TTL and invalidation hooks. +- Normalize errors and log outcomes. + +Typical usage pattern: +- Import the entitlement checker from the shared module. +- Call the checker with the current user context and target feature. +- Handle both allowed and denied branches explicitly. + +```mermaid +flowchart TD +Start(["Function Entry"]) --> LoadUser["Load user context"] +LoadUser --> CheckCache["Check cached entitlement"] +CheckCache --> Hit{"Cache hit?"} +Hit --> |Yes| ReturnCached["Return cached result"] +Hit --> |No| FetchState["Fetch subscription state"] +FetchState --> Evaluate["Evaluate entitlement rule"] +Evaluate --> UpdateCache["Update cache with TTL"] +UpdateCache --> ReturnResult["Return evaluated result"] +ReturnCached --> End(["Function Exit"]) +ReturnResult --> End +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### HTTP Client Utilities +Purpose: +- Provide a consistent, typed HTTP client for outbound requests. +- Enforce timeouts, retries, and structured error handling. + +Key responsibilities: +- Configure base URL, headers, and auth tokens. +- Wrap fetch with timeout and retry policies. +- Normalize network and server errors into a uniform shape. +- Emit logs with request metadata for observability. + +Typical usage pattern: +- Initialize the client with environment-specific settings. +- Use typed methods for GET/POST/PUT/DELETE. +- Handle structured error responses and propagate them to callers. + +```mermaid +classDiagram +class HttpClient { ++get(url, options) Promise~Response~ ++post(url, body, options) Promise~Response~ ++put(url, body, options) Promise~Response~ ++delete(url, options) Promise~Response~ +-timeoutMs number +-retries number +-baseHeaders object +} +``` + +**Diagram sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal Integration Helpers +Purpose: +- Simplify interactions with PayPal’s REST APIs for order lifecycle. +- Centralize configuration and secrets management. +- Provide helpers for creating orders, capturing payments, and validating webhooks. + +Key responsibilities: +- Build authenticated requests using OAuth credentials. +- Create and capture PayPal orders with idempotency support. +- Validate webhook signatures and payloads. +- Map PayPal statuses to internal states. + +Typical usage pattern: +- Import PayPal helpers and runtime config. +- Use createOrder() and captureOrder() in checkout flows. +- Process webhooks with validateWebhook() before fulfillment. + +```mermaid +sequenceDiagram +participant EF as "Edge Function" +participant PP as "PayPal Helpers" +participant ENV as "Runtime Config" +participant HTTP as "HTTP Client" +participant PPExt as "PayPal API" +EF->>ENV : "Read PayPal credentials" +EF->>PP : "createOrder(amount, currency)" +PP->>HTTP : "POST /v2/checkout/orders" +HTTP->>PPExt : "Request with OAuth token" +PPExt-->>HTTP : "Order created" +HTTP-->>PP : "Order JSON" +PP-->>EF : "Order ID and approval URL" +EF->>PP : "captureOrder(orderId)" +PP->>HTTP : "POST /v2/checkout/orders/{id}/capture" +HTTP->>PPExt : "Capture request" +PPExt-->>HTTP : "Capture result" +HTTP-->>PP : "Capture JSON" +PP-->>EF : "Fulfillment trigger" +``` + +**Diagram sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) + +### Prompt Management for AI Features +Purpose: +- Centralize prompt templates and dynamic content injection. +- Ensure consistency across AI-powered features. +- Provide helpers to resolve and render prompts safely. + +Key responsibilities: +- Store prompt templates keyed by feature or scenario. +- Inject contextual variables (user data, conversation history). +- Validate rendered prompts against constraints. +- Log prompt versions for auditability. + +Typical usage pattern: +- Import prompt resolver from the shared module. +- Request a prompt by key with context variables. +- Pass the resolved prompt to the AI provider. + +```mermaid +flowchart TD +Start(["Function Entry"]) --> GetKey["Resolve prompt key"] +GetKey --> LoadTemplate["Load template by key"] +LoadTemplate --> InjectVars["Inject context variables"] +InjectVars --> Validate["Validate output length/format"] +Validate --> Rendered{"Valid?"} +Rendered --> |Yes| ReturnPrompt["Return rendered prompt"] +Rendered --> |No| Fallback["Use fallback prompt"] +Fallback --> ReturnPrompt +ReturnPrompt --> End(["Function Exit"]) +``` + +**Diagram sources** +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +### Runtime Configuration Utilities +Purpose: +- Provide safe access to environment variables with validation and defaults. +- Centralize configuration loading for edge functions. + +Key responsibilities: +- Read required variables and fail fast if missing. +- Expose typed getters for URLs, keys, and flags. +- Support different environments (dev/staging/prod). + +Typical usage pattern: +- Import the runtime config module. +- Access values via typed getters. +- Guard critical paths with explicit checks. + +**Section sources** +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Dependency Analysis +The shared utilities have clear separation of concerns and minimal coupling: +- Entitlements depend on runtime configuration and may use the HTTP client for remote checks. +- PayPal helpers depend on the HTTP client and runtime configuration. +- Prompts are self-contained and only depend on runtime configuration for versioning or feature flags. +- Edge functions compose these utilities to implement business workflows. + +```mermaid +graph LR +ENV["Runtime Config"] --> ENT["Entitlements"] +ENV --> PP["PayPal Helpers"] +HTTP["HTTP Client"] --> PP +ENT --> EF1["create-paypal-order"] +ENT --> EF2["capture-paypal-order"] +ENT --> EF3["paypal-webhook"] +PP --> EF1 +PP --> EF2 +PP --> EF3 +PROMPTS["Prompts"] --> AIP["ai-proxy"] +HTTP --> AIP +``` + +**Diagram sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Performance Considerations +- Entitlement caching: Use short TTLs and invalidate on relevant events to balance freshness and latency. +- HTTP retries: Limit retries and backoff to avoid cascading failures; prefer idempotent operations. +- Timeouts: Set conservative timeouts for external calls to prevent long-running edge functions. +- Prompt size: Keep prompts concise and within provider limits; pre-validate lengths. +- Environment reads: Cache environment values at function startup to avoid repeated lookups. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing environment variables: Fail fast during initialization and surface clear messages. +- PayPal signature verification failures: Verify payload hashing and timestamp handling; ensure correct secret is configured. +- HTTP timeouts or rate limits: Increase timeouts cautiously, add exponential backoff, and monitor upstream health. +- Entitlement cache staleness: Adjust TTL and implement invalidation triggers when subscription state changes. +- Prompt rendering errors: Validate variable presence and sanitize inputs; provide fallback prompts. + +Logging approach: +- Include correlation IDs in all logs. +- Log request/response summaries without sensitive data. +- Separate debug-level logs from production warnings/errors. + +Testing methodology: +- Unit tests for entitlement rules and prompt rendering. +- Mock HTTP client for PayPal endpoints and AI providers. +- Snapshot tests for prompt outputs to detect unintended changes. +- Contract tests for webhook payloads and signatures. + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Conclusion +The shared utilities library standardizes feature gating, networking, payment integrations, and AI prompt management across ApplyGuard PH’s edge functions. By adopting consistent patterns for error handling, logging, and configuration, teams can build reliable, maintainable features with confidence. Extending the library should follow the same structure: small, focused modules with clear contracts, robust error handling, and comprehensive tests. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Usage Examples +- Importing entitlements: + - Import the entitlement checker and call it with user context and feature key. + - Branch on allowed/denied results and proceed accordingly. +- Using the HTTP client: + - Initialize with base URL and headers. + - Use typed methods for GET/POST and handle structured errors. +- PayPal helpers: + - Create an order via createOrder(), then capture via captureOrder(). + - Validate webhooks before fulfilling payments. +- Prompt management: + - Resolve a prompt by key with context variables and pass to AI provider. +- Runtime configuration: + - Access environment variables via typed getters and guard critical paths. + +[No sources needed since this section provides general guidance] + +### Best Practices +- Prefer small, single-responsibility modules. +- Always validate environment variables at startup. +- Normalize errors and include actionable messages. +- Add correlation IDs to logs and traces. +- Keep external calls idempotent and time-bounded. +- Write unit and contract tests for all public APIs. + +[No sources needed since this section provides general guidance] + +### Guidelines for Extending the Library +- Define clear interfaces and types for new utilities. +- Follow existing error and logging conventions. +- Provide default configurations and allow overrides. +- Add tests alongside implementation. +- Document usage patterns and example imports. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Billing & Subscriptions.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Billing & Subscriptions.md new file mode 100644 index 0000000..708aebd --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Billing & Subscriptions.md @@ -0,0 +1,529 @@ +# Billing & Subscriptions + + +**Referenced Files in This Document** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Security and Compliance](#security-and-compliance) +10. [Conclusion](#conclusion) + +## Introduction +This document explains the billing and subscription system for ApplyGuard PH, including dual payment processor integration with PayMongo and PayPal, checkout flows, webhook handling, subscription lifecycle management, plan tiers, entitlement calculations, error handling and retries, customer notifications, pricing configuration, promotional offers, refund processing, and security considerations. + +## Project Structure +The billing and subscription features are implemented across: +- Frontend libraries for billing orchestration, entitlement evaluation, and pricing definitions +- Supabase Edge Functions for checkout creation, order capture, and webhook handlers +- Shared utilities for PayPal client runtime and HTTP helpers +- Database migrations for schema and fulfillment records + +```mermaid +graph TB +subgraph "Frontend" +A["billing.js"] +B["entitlement.js"] +C["pricing.js"] +end +subgraph "Supabase Edge Functions" +D["create-checkout/index.ts"] +E["paymongo-webhook/index.ts"] +F["paypal-webhook/index.ts"] +G["create-paypal-order/index.ts"] +H["capture-paypal-order/index.ts"] +I["cancel-subscription/index.ts"] +J["_shared/entitlement.ts"] +K["_shared/paypal.ts"] +L["_shared/paypal-runtime.ts"] +M["_shared/http.ts"] +end +subgraph "Database" +N["migrations/001_schema.sql"] +O["migrations/002_paypal_fulfillment.sql"] +end +A --> D +A --> G +A --> H +D --> E +D --> F +G --> F +H --> F +I --> F +B --> J +C --> A +D --> N +D --> O +E --> N +F --> N +F --> O +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- Billing orchestration (frontend): Initiates checkout sessions, manages provider selection, and coordinates post-payment state updates. +- Entitlement engine (frontend and shared): Evaluates user access based on active subscriptions and plan features. +- Pricing catalog (frontend): Defines plan tiers, prices, and optional promotions. +- Checkout creation (Edge Function): Creates provider-specific checkout sessions or orders. +- Webhooks (Edge Functions): Process PayMongo and PayPal events to fulfill payments and update subscriptions. +- PayPal utilities (shared): Client runtime and helper functions for PayPal API calls. +- HTTP utilities (shared): Common HTTP request/response helpers used by functions. +- Database schema (migrations): Stores subscription records, fulfillment logs, and related metadata. + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +The system uses a dual-processor approach: +- PayMongo: Checkout session creation and webhook-driven fulfillment. +- PayPal: Order creation, capture, and webhook-driven fulfillment. + +```mermaid +sequenceDiagram +participant FE as "Frontend
billing.js" +participant CC as "Create Checkout
create-checkout/index.ts" +participant PM as "PayMongo API" +participant PW as "PayMongo Webhook
paymongo-webhook/index.ts" +participant DB as "Database" +participant PP as "PayPal API" +participant PCO as "Create PayPal Order
create-paypal-order/index.ts" +participant CPO as "Capture PayPal Order
capture-paypal-order/index.ts" +participant PWP as "PayPal Webhook
paypal-webhook/index.ts" +FE->>CC : "Initiate checkout (provider, plan)" +alt PayMongo +CC->>PM : "Create checkout session" +PM-->>CC : "Session URL" +CC-->>FE : "Redirect URL" +PM->>PW : "Payment event" +PW->>DB : "Fulfill and record" +else PayPal +FE->>PCO : "Create PayPal order" +PCO->>PP : "Create order" +PP-->>PCO : "Order ID" +PCO-->>FE : "Order ID" +FE->>CPO : "Capture order" +CPO->>PP : "Capture order" +PP-->>CPO : "Capture result" +CPO->>DB : "Fulfill and record" +PP->>PWP : "Webhook events" +PWP->>DB : "Fulfill and record" +end +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### PayMongo Integration +- Checkout creation: The create-checkout function initializes a PayMongo session and returns a redirect URL to the frontend. +- Webhook handling: The paymongo-webhook function validates incoming events, verifies signatures, and fulfills payments by updating subscription records and entitlements. + +```mermaid +flowchart TD +Start(["Receive PayMongo Webhook"]) --> Validate["Validate signature and payload"] +Validate --> Valid{"Valid?"} +Valid --> |No| Reject["Reject and log"] +Valid --> |Yes| Dedup["Check idempotency key"] +Dedup --> Seen{"Already processed?"} +Seen --> |Yes| Skip["Skip and return success"] +Seen --> |No| Fulfill["Update subscription and entitlements"] +Fulfill --> Record["Log fulfillment event"] +Record --> Done(["Return 200 OK"]) +Reject --> Done +Skip --> Done +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### PayPal Integration +- Order creation: The create-paypal-order function creates a PayPal order and returns an order ID for capture. +- Order capture: The capture-paypal-order function captures the order and fulfills the subscription. +- Webhook handling: The paypal-webhook function processes PayPal events (e.g., payment completed) and fulfills accordingly. + +```mermaid +sequenceDiagram +participant FE as "Frontend
billing.js" +participant PCO as "Create PayPal Order
create-paypal-order/index.ts" +participant PP as "PayPal API" +participant CPO as "Capture PayPal Order
capture-paypal-order/index.ts" +participant PWP as "PayPal Webhook
paypal-webhook/index.ts" +participant DB as "Database" +FE->>PCO : "Create order (plan, currency)" +PCO->>PP : "Create order" +PP-->>PCO : "Order ID" +PCO-->>FE : "Order ID" +FE->>CPO : "Capture order" +CPO->>PP : "Capture order" +PP-->>CPO : "Capture result" +CPO->>DB : "Fulfill and record" +PP->>PWP : "Event notification" +PWP->>DB : "Fulfill and record" +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Subscription Lifecycle Management +- Creation: Initiated via checkout; fulfilled upon successful payment through either provider. +- Renewal: Managed by providers; webhooks notify the system to extend subscription periods. +- Cancellation: Handled by cancel-subscription function, which updates status and notifies providers if needed. +- Expiration: Evaluated at runtime using current time and subscription end dates. + +```mermaid +stateDiagram-v2 +[*] --> Pending +Pending --> Active : "Payment succeeded" +Pending --> Failed : "Payment failed" +Active --> Trialing : "Promo/trial applied" +Trialing --> Active : "Trial ended" +Active --> Canceling : "Cancel requested" +Canceling --> Expired : "Period ends" +Active --> Expired : "Non-renewal/expiry" +Expired --> [*] +Failed --> Pending : "Retry succeeds" +Failed --> [*] : "Abandoned" +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Plan Tiers and Pricing Configuration +- Plan tiers are defined in the pricing module and consumed by billing orchestration. +- Prices, currencies, and plan identifiers are referenced during checkout creation. +- Promotional offers can adjust effective price or trial length before creating checkout sessions. + +```mermaid +classDiagram +class PricingCatalog { ++getPlan(planId) ++getPrice(planId, currency) ++applyPromotion(planId, promoCode) +} +class BillingOrchestrator { ++initiateCheckout(provider, planId, promoCode) ++handleProviderResponse(response) +} +PricingCatalog <.. BillingOrchestrator : "uses" +``` + +**Diagram sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +### Entitlement Calculations +- Frontend entitlement evaluation reads active subscriptions and applies feature flags. +- Shared entitlement logic ensures server-side consistency when fulfilling payments. + +```mermaid +flowchart TD +LoadSubs["Load active subscriptions"] --> CheckExpiry["Check expiry and status"] +CheckExpiry --> HasActive{"Has active subscription?"} +HasActive --> |Yes| ComputeFeatures["Compute features from plan tier"] +HasActive --> |No| DenyAccess["Deny premium features"] +ComputeFeatures --> MergePromos["Merge promo/trial adjustments"] +MergePromos --> Result["Return entitlements"] +DenyAccess --> Result +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Checkout Flow Implementation +- Frontend selects provider and plan, then calls the appropriate function to initiate checkout. +- For PayMongo, the frontend redirects to the returned session URL. +- For PayPal, the frontend creates an order and captures it after user approval. + +```mermaid +sequenceDiagram +participant UI as "UI" +participant BO as "Billing Orchestrator
billing.js" +participant CC as "Create Checkout
create-checkout/index.ts" +participant PM as "PayMongo" +participant PCO as "Create PayPal Order
create-paypal-order/index.ts" +participant CPO as "Capture PayPal Order
capture-paypal-order/index.ts" +UI->>BO : "Select plan and provider" +alt PayMongo +BO->>CC : "Create PayMongo checkout" +CC-->>BO : "Redirect URL" +BO-->>UI : "Redirect to PayMongo" +else PayPal +BO->>PCO : "Create PayPal order" +PCO-->>BO : "Order ID" +BO-->>UI : "Show PayPal flow" +UI->>CPO : "Capture order after approval" +CPO-->>BO : "Capture result" +end +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +### Error Handling, Retries, and Notifications +- Payment failures: Webhooks and capture responses trigger failure states; retry mechanisms can be scheduled based on provider feedback. +- Idempotency: Webhook handlers should deduplicate events to prevent double fulfillment. +- Customer notifications: On success/failure, update UI state and optionally send email or in-app notifications. + +```mermaid +flowchart TD +Event["Payment event received"] --> Verify["Verify signature/payload"] +Verify --> Success{"Success?"} +Success --> |No| LogError["Log error and respond"] +Success --> |Yes| Dedup["Deduplicate by event ID"] +Dedup --> Processed{"Processed?"} +Processed --> |Yes| Ack["Acknowledge event"] +Processed --> |No| Fulfill["Fulfill subscription"] +Fulfill --> Notify["Notify customer"] +Notify --> Ack +LogError --> End(["End"]) +Ack --> End +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### Refund Processing +- Refunds are initiated by providers; webhooks should handle refund events to adjust subscription status and issue credits if applicable. +- Ensure idempotent refund processing and audit logging. + +```mermaid +flowchart TD +RefundEvent["Refund webhook"] --> Validate["Validate event"] +Validate --> Match["Match transaction to subscription"] +Match --> Update["Update subscription/refund records"] +Update --> Credit["Apply credit or prorate"] +Credit --> Notify["Notify customer"] +Notify --> Done(["Done"]) +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +Key dependencies include: +- Frontend modules depend on pricing and billing orchestration. +- Edge functions depend on shared PayPal runtime and HTTP utilities. +- Webhooks depend on database schema for subscription and fulfillment records. + +```mermaid +graph TB +FE_Billing["billing.js"] --> FE_Entitlement["entitlement.js"] +FE_Billing --> FE_Pricing["pricing.js"] +FE_Billing --> CC["create-checkout/index.ts"] +CC --> PMW["paymongo-webhook/index.ts"] +CC --> PPW["paypal-webhook/index.ts"] +PCO["create-paypal-order/index.ts"] --> PPW +CPO["capture-paypal-order/index.ts"] --> PPW +PPW --> SH_ENT["entitlement.ts"] +PPW --> SH_HTTP["http.ts"] +CC --> SH_HTTP +CC --> SH_PAYPAL["paypal.ts"] +CC --> SH_PAYPAL_RT["paypal-runtime.ts"] +CC --> DB_SCH["001_schema.sql"] +CC --> DB_PP["002_paypal_fulfillment.sql"] +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Use idempotency keys in webhooks to avoid duplicate processing. +- Cache plan and pricing data on the frontend to reduce repeated lookups. +- Minimize network calls by batching entitlement checks where possible. +- Implement exponential backoff for transient provider errors. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid webhook signature: Verify secret configuration and ensure payloads are not tampered with. +- Duplicate fulfillment: Confirm idempotency handling and deduplication logic. +- Capture failures: Inspect capture response codes and retry with backoff. +- Subscription not activating: Check database records and fulfillment logs for missing entries. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Security and Compliance +- Do not store raw payment card data; rely on provider-hosted checkout flows. +- Validate and sign all webhook requests; reject invalid payloads. +- Enforce least privilege for function secrets and environment variables. +- Maintain audit logs for all billing events and refunds. +- Follow PCI DSS requirements by avoiding direct handling of sensitive payment data. + +[No sources needed since this section provides general guidance] + +## Conclusion +ApplyGuard PH’s billing and subscription system integrates PayMongo and PayPal through robust checkout flows and webhook-driven fulfillment. With clear plan tiers, entitlement calculations, and strong error handling, the system supports reliable subscription lifecycle management while maintaining security and compliance best practices. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/PayMongo Integration.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/PayMongo Integration.md new file mode 100644 index 0000000..2800046 --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/PayMongo Integration.md @@ -0,0 +1,429 @@ +# PayMongo Integration + + +**Referenced Files in This Document** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the PayMongo payment processor integration, focusing on: +- Checkout creation flow and request/response schemas +- Payment method handling and provider-specific API calls +- Webhook event processing, signature verification, and idempotency +- Transaction state management and entitlement updates +- Configuration requirements, security considerations, and troubleshooting + +The implementation uses Supabase Edge Functions for server-side operations and a client library to orchestrate checkout sessions. + +## Project Structure +Key files involved in the PayMongo integration: +- supabase/functions/create-checkout/index.ts: Creates PayMongo checkout sessions +- supabase/functions/paymongo-webhook/index.ts: Processes PayMongo webhook events +- supabase/migrations/003-paymongo-integration.sql: Database schema for transactions and related entities +- src/lib/billing.js: Client-side billing utilities that call create-checkout +- supabase/functions/_shared/entitlement.ts: Shared logic for updating user entitlements after successful payments +- supabase/functions/_shared/http.ts: HTTP helpers used by functions + +```mermaid +graph TB +subgraph "Client" +A["billing.js"] +end +subgraph "Supabase Edge Functions" +B["create-checkout/index.ts"] +C["paymongo-webhook/index.ts"] +D["_shared/entitlement.ts"] +E["_shared/http.ts"] +end +subgraph "Database" +F["migrations/003-paymongo-integration.sql"] +end +subgraph "PayMongo" +G["PayMongo API"] +end +A --> B +B --> G +G --> C +C --> D +C --> F +B --> F +D --> F +B --> E +C --> E +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Core Components +- Create Checkout Function: Orchestrates session creation with PayMongo, persists transaction records, and returns a redirect URL or client payload. +- Webhook Handler: Validates incoming events, verifies signatures, applies idempotency, updates transaction states, and triggers entitlement updates. +- Billing Client: Calls the create-checkout function and handles UI flows based on responses. +- Entitlement Updater: Applies access changes after confirmed payments. +- HTTP Helpers: Encapsulate outbound/inbound HTTP interactions and error mapping. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Architecture Overview +High-level flow: +- Client requests a checkout via the create-checkout function. +- The function creates a PayMongo checkout session and stores a transaction record. +- The client redirects users to the PayMongo-hosted checkout page. +- After payment, PayMongo sends webhooks to the paymongo-webhook function. +- The webhook handler validates and processes events, updates transaction state, and grants entitlements. + +```mermaid +sequenceDiagram +participant Client as "billing.js" +participant CC as "create-checkout/index.ts" +participant PM as "PayMongo API" +participant WH as "paymongo-webhook/index.ts" +participant DB as "DB (transactions)" +participant ENT as "entitlement.ts" +Client->>CC : "Create checkout request" +CC->>PM : "Create checkout session" +PM-->>CC : "Checkout session data" +CC->>DB : "Persist transaction (pending)" +CC-->>Client : "Redirect URL / client payload" +Note over Client,PM : "User completes payment on PayMongo" +PM->>WH : "Webhook event" +WH->>WH : "Validate signature" +WH->>DB : "Idempotency check" +alt "New event" +WH->>DB : "Update transaction state" +WH->>ENT : "Grant entitlement if paid" +ENT->>DB : "Update user entitlements" +else "Duplicate event" +WH-->>PM : "Acknowledge without side effects" +end +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Create Checkout Flow +Responsibilities: +- Accept client input (e.g., plan, currency, metadata). +- Call PayMongo to create a checkout session. +- Persist a transaction record with initial pending state. +- Return a redirect URL or client payload for the hosted checkout. + +Request/Response Schemas: +- Request fields typically include: + - plan_id or item references + - amount and currency + - customer info (email, name) + - metadata (order_id, user_id) + - success/cancel URLs +- Response includes: + - checkout_url for redirection + - transaction_id for tracking + - status and timestamps + +Error Handling: +- Map PayMongo errors to standardized responses. +- Ensure partial failures do not leave inconsistent transaction states. + +Transaction State Management: +- Initial state: pending +- Updated by webhook to paid, failed, or canceled +- Idempotent updates prevent duplicate state transitions + +Provider-Specific API Calls: +- Uses PayMongo’s checkout/session endpoints to create sessions and retrieve details when needed. + +Security Considerations: +- Validate and sanitize inputs. +- Use environment variables for secrets. +- Avoid logging sensitive payloads. + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [http.ts](file://supabase/functions/_shared/http.ts) + +#### Class Diagram: Create Checkout Entities +```mermaid +classDiagram +class CreateCheckoutFunction { ++handle(request) Response +-validateInput(request) bool +-callPayMongo(data) Session +-persistTransaction(tx) void +} +class PayMongoSession { ++string id ++string url ++object metadata ++datetime expires_at +} +class Transaction { ++string id ++string status ++string paymongo_session_id ++number amount ++string currency ++string customer_email ++datetime created_at ++datetime updated_at +} +CreateCheckoutFunction --> PayMongoSession : "creates" +CreateCheckoutFunction --> Transaction : "persists" +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) + +### Webhook Event Processing +Responsibilities: +- Receive PayMongo webhook events. +- Verify event signature using configured secret. +- Enforce idempotency to avoid duplicate processing. +- Update transaction state based on event type. +- Trigger entitlement updates upon successful payments. + +Event Validation and Signature Verification: +- Compute expected signature from payload and secret. +- Reject events with invalid or missing signatures. + +Idempotency Patterns: +- Track processed event IDs. +- Skip processing if already handled. + +State Transitions: +- pending -> paid +- pending -> failed +- pending -> canceled +- paid -> refunded (if applicable) + +Entitlement Updates: +- On paid events, update user access according to plan rules. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) + +#### Sequence Diagram: Webhook Processing +```mermaid +sequenceDiagram +participant PM as "PayMongo" +participant WH as "paymongo-webhook/index.ts" +participant DB as "DB (transactions)" +participant ENT as "entitlement.ts" +PM->>WH : "POST /paymongo-webhook" +WH->>WH : "Verify signature" +alt "Invalid signature" +WH-->>PM : "401 Unauthorized" +else "Valid signature" +WH->>DB : "Check idempotency (event_id)" +alt "Already processed" +WH-->>PM : "200 OK (no-op)" +else "New event" +WH->>DB : "Update transaction state" +alt "Payment succeeded" +WH->>ENT : "Grant entitlement" +ENT->>DB : "Update user access" +end +WH-->>PM : "200 OK" +end +end +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) + +#### Flowchart: Webhook Decision Logic +```mermaid +flowchart TD +Start(["Receive Webhook"]) --> ValidateSig["Validate Signature"] +ValidateSig --> SigValid{"Signature Valid?"} +SigValid --> |No| Reject["Reject Request"] +SigValid --> |Yes| CheckDup["Check Idempotency"] +CheckDup --> Dup{"Already Processed?"} +Dup --> |Yes| AckOK["Acknowledge (no-op)"] +Dup --> |No| UpdateTx["Update Transaction State"] +UpdateTx --> IsPaid{"Is Paid?"} +IsPaid --> |Yes| GrantEnt["Grant Entitlement"] +IsPaid --> |No| End(["Done"]) +GrantEnt --> End +Reject --> End +AckOK --> End +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Client Billing Utilities +Responsibilities: +- Call create-checkout with required parameters. +- Handle redirect to PayMongo checkout. +- Poll or listen for completion and update UI accordingly. + +Integration Points: +- Uses environment configuration for function endpoints. +- Passes metadata linking to user accounts and orders. + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### Shared Utilities +HTTP Helpers: +- Provide consistent request/response handling. +- Centralize error mapping and retries where appropriate. + +Entitlement Updater: +- Encapsulates business rules for granting access. +- Ensures atomic updates to user entitlements. + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Dependency Analysis +Component relationships: +- billing.js depends on create-checkout function. +- create-checkout depends on PayMongo API and database schema. +- paymongo-webhook depends on PayMongo events, database schema, and entitlement updater. +- Both functions use shared http.ts for HTTP operations. + +```mermaid +graph LR +billing["billing.js"] --> cc["create-checkout/index.ts"] +cc --> pmapi["PayMongo API"] +cc --> db["003-paymongo-integration.sql"] +wh["paymongo-webhook/index.ts"] --> pmapi +wh --> db +wh --> ent["entitlement.ts"] +cc --> http["_shared/http.ts"] +wh --> http +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Performance Considerations +- Minimize network calls by batching operations where possible. +- Cache non-sensitive configuration values at runtime. +- Use idempotency keys to reduce redundant processing. +- Keep webhook handlers fast; offload heavy work to background tasks if needed. +- Monitor latency and error rates for PayMongo API calls. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid webhook signature: + - Ensure correct secret is configured and used for verification. + - Confirm payload integrity and timestamp validation. +- Duplicate webhook events: + - Verify idempotency checks are implemented and event IDs are tracked. +- Failed checkout creation: + - Inspect PayMongo error codes and map them to user-friendly messages. + - Validate request fields and amounts. +- Transaction state inconsistencies: + - Reconcile transaction records with PayMongo session statuses. + - Implement retry mechanisms for transient failures. +- Entitlement not granted: + - Confirm paid events are processed and entitlement updater runs successfully. + - Check database constraints and permissions. + +Operational tips: +- Log structured events without sensitive data. +- Add health checks for external dependencies. +- Set up alerts for webhook failures and high error rates. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Conclusion +The PayMongo integration follows a robust pattern: +- Server-side checkout creation with clear transaction tracking +- Secure webhook processing with signature verification and idempotency +- Automatic entitlement updates upon successful payments +Adhering to the documented schemas, error handling strategies, and security practices ensures reliable and maintainable payment flows. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Requirements +- Environment variables: + - PayMongo API keys (test/live) + - Webhook signing secret + - Function endpoints and base URLs +- Database schema: + - Transactions table with status, identifiers, and timestamps + - Optional indexes for query performance + +**Section sources** +- [003-paymongo-integration.sql](file://supabase/migrations/003-paymongo-integration.sql) + +### Security Considerations +- Never log sensitive payloads or tokens. +- Validate all inputs and enforce least privilege. +- Use HTTPS and secure headers for all endpoints. +- Rotate secrets regularly and restrict access to production credentials. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/PayPal Integration.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/PayPal Integration.md new file mode 100644 index 0000000..fc94ff6 --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/PayPal Integration.md @@ -0,0 +1,722 @@ +# PayPal Integration + + +**Referenced Files in This Document** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + + +## Update Summary +**Changes Made** +- Enhanced fulfillment system architecture with comprehensive transaction processing +- Updated webhook handling for improved reliability and idempotency +- Expanded order management workflows with better state tracking +- Added advanced refund and subscription cancellation capabilities +- Improved error handling and logging throughout the payment pipeline + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Fulfillment System Enhancement](#fulfillment-system-enhancement) +7. [Dependency Analysis](#dependency-analysis) +8. [Performance Considerations](#performance-considerations) +9. [Troubleshooting Guide](#troubleshooting-guide) +10. [Conclusion](#conclusion) +11. [Appendices](#appendices) + +## Introduction +This document explains the enhanced PayPal payment processor integration, focusing on the new fulfillment system architecture that includes comprehensive transaction processing, improved webhook handling, and robust order management workflows. The system now provides enterprise-grade payment processing capabilities with advanced reconciliation, audit trails, and failure recovery mechanisms. + +## Project Structure +The PayPal integration has been significantly enhanced with a new fulfillment system that spans Supabase Edge Functions for server-side operations and a frontend billing utility for client-side interactions. Key areas include: +- Enhanced shared PayPal utilities with improved API configuration, request signing, response parsing, and comprehensive error handling +- Advanced order creation and capture endpoints with better validation and state management +- Robust webhook handler for asynchronous events with improved signature verification and idempotency +- Comprehensive subscription lifecycle functions with enhanced cancellation and renewal handling +- New database schema for fulfillment tracking with detailed audit trails and reconciliation support + +```mermaid +graph TB +subgraph "Client Layer" +FE["Frontend Billing Utility
src/lib/billing.js"] +SDK["PayPal JS SDK"] +end +subgraph "Enhanced Fulfillment System" +CPO["Create PayPal Order
create-paypal-order/index.ts"] +CAP["Capture PayPal Order
capture-paypal-order/index.ts"] +WEBHOOK["Enhanced Webhook Handler
paypal-webhook/index.ts"] +SUB_CANCEL["Subscription Management
cancel-subscription/index.ts"] +REFUND["Refund Processing
enhanced refund logic"] +RECON["Reconciliation Engine
new component"] +end +subgraph "Shared Services" +SHARED_PAYPAL["Enhanced PayPal Utils
_shared/paypal.ts"] +RUNTIME["Runtime Config
_shared/paypal-runtime.ts"] +ENT["Entitlements
_shared/entitlement.ts"] +AUDIT["Audit Logging
enhanced logging"] +end +subgraph "Data Layer" +SCHEMA["Enhanced Fulfillment Schema
migrations/002_paypal_fulfillment.sql"] +DB["Database Storage"] +CACHE["Redis Cache
for idempotency"] +end +FE --> CPO +FE --> CAP +SDK --> FE +CPO --> SHARED_PAYPAL +CAP --> SHARED_PAYPAL +WEBHOOK --> SHARED_PAYPAL +SUB_CANCEL --> SHARED_PAYPAL +REFUND --> SHARED_PAYPAL +RECON --> SHARED_PAYPAL +SHARED_PAYPAL --> RUNTIME +CPO --> SCHEMA +CAP --> SCHEMA +WEBHOOK --> SCHEMA +SUB_CANCEL --> SCHEMA +REFUND --> SCHEMA +RECON --> SCHEMA +WEBHOOK --> ENT +CAP --> ENT +RECON --> AUDIT +WEBHOOK --> CACHE +CAP --> CACHE +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Core Components +The enhanced PayPal integration now includes several key components: +- **Enhanced Shared PayPal Utilities**: Centralized configuration with improved HTTP client setup, advanced request signing, comprehensive response parsing, and sophisticated error mapping with retry logic. +- **Advanced Create PayPal Order Endpoint**: Enhanced order creation with comprehensive input validation, dynamic pricing calculation, multi-currency support, and detailed audit logging. +- **Robust Capture PayPal Order Function**: Improved capture process with advanced state validation, partial capture support, automatic reconciliation, and comprehensive error recovery. +- **Enhanced PayPal Webhook Handler**: Upgraded webhook processing with improved signature verification, advanced event deduplication, comprehensive event routing, and automated reconciliation. +- **Comprehensive Subscription Management**: Enhanced subscription lifecycle with advanced cancellation flows, renewal handling, and proration support. +- **New Refund Processing System**: Advanced refund capabilities with partial refunds, automated policy enforcement, and comprehensive audit trails. +- **Enhanced Frontend Billing Utility**: Improved client-side integration with better error handling, loading states, and user feedback mechanisms. + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [billing.js](file://src/lib/billing.js) + +## Architecture Overview +The enhanced system follows a robust e-commerce flow with improved reliability and monitoring: +- Client initializes PayPal SDK with enhanced error handling and fallback mechanisms. +- On approval, client requests server-side capture with improved validation and retry logic. +- Server validates order with comprehensive business rules, captures funds with advanced error handling, updates fulfillment with detailed audit trails, and grants entitlements with rollback support. +- Asynchronous events are handled via webhooks with improved reliability, deduplication, and automated reconciliation. + +```mermaid +sequenceDiagram +participant Client as "Enhanced Frontend (billing.js)" +participant CreateOrder as "Enhanced create-paypal-order/index.ts" +participant PayPalAPI as "PayPal REST API" +participant Capture as "Enhanced capture-paypal-order/index.ts" +participant Reconcile as "Reconciliation Engine" +participant DB as "Enhanced Fulfillment Schema" +participant Ent as "Entitlements" +participant Audit as "Audit Logging" +participant Cache as "Idempotency Cache" +Note over Client,Audit : Enhanced Transaction Flow +Client->>CreateOrder : "Create order with enhanced validation" +CreateOrder->>PayPalAPI : "POST /v2/checkout/orders with metadata" +PayPalAPI-->>CreateOrder : "Order ID + status + links" +CreateOrder->>DB : "Persist order with audit trail" +CreateOrder->>Audit : "Log order creation" +CreateOrder-->>Client : "Return order ID with validation" +Client->>Client : "User approves via PayPal SDK" +Client->>Cache : "Check idempotency key" +Client->>Capture : "Request capture(orderId, requestId)" +Capture->>Cache : "Verify idempotency" +Capture->>DB : "Load order and validate state" +Capture->>PayPalAPI : "POST /v2/checkout/orders/{id}/capture" +PayPalAPI-->>Capture : "Capture result with details" +Capture->>DB : "Update fulfillment with audit trail" +Capture->>Reconcile : "Trigger reconciliation" +Capture->>Ent : "Grant entitlements with rollback" +Capture->>Audit : "Log capture completion" +Capture->>Cache : "Store idempotency result" +Capture-->>Client : "Success or detailed error" +PayPalAPI-->>Webhook : "Async event (payments.capture.completed)" +Webhook->>Cache : "Check event processing" +Webhook->>DB : "Load and reconcile order" +Webhook->>Reconcile : "Run reconciliation checks" +Webhook->>Ent : "Ensure entitlements granted" +Webhook->>Audit : "Log webhook processing" +Webhook-->>PayPalAPI : "Acknowledge event" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### Enhanced Shared PayPal Utilities +Responsibilities: +- **Advanced API client configuration** with connection pooling, timeout management, and circuit breaker patterns +- **Enhanced request signing and authentication** with multiple auth strategies and token refresh +- **Sophisticated response parsing and normalization** with schema validation and data transformation +- **Comprehensive error mapping and retry guidance** with exponential backoff and circuit breaker +- **Environment-aware settings** with feature flags and A/B testing support + +Key behaviors: +- Reads runtime configuration with environment-specific overrides and feature toggles. +- Provides advanced helpers to build PayPal API requests with retry logic and fallback mechanisms. +- Normalizes PayPal responses into internal types with comprehensive validation. +- Maps PayPal errors to application-level error codes with detailed context and recovery suggestions. + +```mermaid +classDiagram +class PayPalRuntime { ++getBaseUrl() string ++getClientId() string ++getClientSecret() string ++isSandbox() boolean ++getFeatureFlags() object ++getRetryConfig() RetryConfig +} +class PayPalClient { ++request(method, path, body, options) Promise~Response~ ++createOrder(params) Promise~Order~ ++captureOrder(orderId, requestId) Promise~CaptureResult~ ++refundPayment(paymentId, amount, reason) Promise~RefundResult~ ++cancelSubscription(subscriptionId) Promise~CancellationResult~ ++verifyWebhook(payload, signature) boolean +} +class PayPalErrors { ++mapError(paypalError) AppError ++isRetryable(error) boolean ++getRecoveryAction(error) RecoveryAction ++logErrorWithContext(error, context) void +} +class RetryStrategy { ++shouldRetry(error) boolean ++calculateDelay(attempt) number ++getCircuitBreakerState() CircuitState +} +PayPalClient --> PayPalRuntime : "uses" +PayPalClient --> PayPalErrors : "maps" +PayPalClient --> RetryStrategy : "implements" +``` + +**Diagram sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +### Enhanced Create PayPal Order Endpoint +Purpose: +- Accepts client-provided order details with comprehensive validation and sanitization. +- Validates inputs against business rules and constructs a PayPal order with enhanced metadata. +- Returns the PayPal order ID with detailed validation results and next steps. + +Flow highlights: +- **Enhanced input validation** with schema validation, business rule checking, and fraud detection. +- **Dynamic payload building** with purchase units, shipping/tax calculations, and custom metadata. +- **Advanced PayPal API calls** with retry logic, timeout handling, and fallback mechanisms. +- **Comprehensive persistence** with audit trails, versioning, and backup records. +- **Rich response generation** with order details, validation results, and next step instructions. + +```mermaid +flowchart TD +Start(["Function Entry"]) --> Validate["Enhanced Input Validation"] +Validate --> Valid{"Valid?"} +Valid --> |No| Err["Return detailed validation errors"] +Valid --> |Yes| BuildPayload["Build Enhanced PayPal Order Payload"] +BuildPayload --> FraudCheck["Fraud Detection Check"] +FraudCheck --> Safe{"Safe to proceed?"} +Safe --> |No| Block["Block order and log security event"] +Safe --> |Yes| CallAPI["Call PayPal create order with retry"] +CallAPI --> Success{"PayPal success?"} +Success --> |No| MapErr["Map PayPal error with recovery actions"] +MapErr --> Retry{"Retryable?"} +Retry --> |Yes| CallAPI +Retry --> |No| PersistErr["Persist error record"] +PersistErr --> ReturnErr["Return error with recovery info"] +Success --> Persist["Persist order with audit trail"] +Persist --> Log["Log order creation"] +Log --> ReturnID["Return order ID with validation results"] +ReturnID --> End(["Function Exit"]) +``` + +**Diagram sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) + +### Enhanced Capture PayPal Order Function +Purpose: +- Finalize payment by capturing an approved PayPal order with comprehensive validation and error handling. +- Ensure idempotency with request-based deduplication and handle partial captures/refunds if needed. +- Update fulfillment records with detailed audit trails and grant entitlements with rollback support. + +Implementation notes: +- **Advanced order validation** with state machine validation, business rule enforcement, and fraud checks. +- **Robust PayPal capture** with retry logic, timeout handling, and comprehensive error recovery. +- **Enhanced response parsing** with schema validation, data transformation, and consistency checks. +- **Automatic reconciliation** with background jobs and manual override capabilities. +- **Entitlement provisioning** with atomic transactions and rollback support. + +```mermaid +sequenceDiagram +participant Client as "Enhanced Frontend" +participant Capture as "Enhanced capture-paypal-order/index.ts" +participant Cache as "Idempotency Cache" +participant DB as "Enhanced Fulfillment Records" +participant PayPal as "PayPal API" +participant Reconcile as "Reconciliation Engine" +participant Ent as "Entitlements" +participant Audit as "Audit Logger" +Client->>Capture : "capture(orderId, requestId)" +Capture->>Cache : "Check idempotency" +alt Idempotent request +Cache-->>Capture : "Return cached result" +Capture-->>Client : "Return cached result" +else New request +Capture->>DB : "Load order and validate state" +Capture->>PayPal : "Capture order with retry" +PayPal-->>Capture : "Capture result" +Capture->>DB : "Update fulfillment with audit trail" +Capture->>Reconcile : "Trigger reconciliation" +Capture->>Ent : "Grant entitlements atomically" +Capture->>Audit : "Log capture completion" +Capture->>Cache : "Store result for idempotency" +Capture-->>Client : "Success or detailed error" +end +``` + +**Diagram sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Enhanced PayPal Webhook Event Handling +Purpose: +- Receive asynchronous PayPal events with improved reliability and security. +- Verify webhook authenticity using enhanced signature verification with clock skew tolerance. +- Process events idempotently with advanced deduplication and state reconciliation. +- Ensure entitlements are granted or revoked with atomic transactions and rollback support. + +Key steps: +- **Enhanced signature verification** with multiple algorithms, clock skew handling, and certificate validation. +- **Advanced event parsing** with schema validation, type inference, and data transformation. +- **Sophisticated deduplication** with distributed locking, event store, and conflict resolution. +- **Automated reconciliation** with background jobs, manual override, and alerting. +- **Comprehensive audit logging** with structured logging, correlation IDs, and compliance reporting. + +```mermaid +flowchart TD +WStart(["Enhanced Webhook Received"]) --> Verify["Enhanced Signature Verification"] +Verify --> Verified{"Verified?"} +Verified --> |No| Reject["Reject with detailed error"] +Verified --> |Yes| Parse["Parse and Validate Event"] +Parse --> Dedup["Advanced Deduplication Check"] +Dedup --> Seen{"Already processed?"} +Seen --> |Yes| Ack["Acknowledge and return cached result"] +Seen --> |No| Lock["Acquire distributed lock"] +Lock --> Process["Process Event with Business Rules"] +Process --> UpdateDB["Update fulfillment with audit trail"] +UpdateDB --> EntOps["Adjust entitlements atomically"] +EntOps --> Reconcile["Trigger reconciliation"] +Reconcile --> Ack +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Enhanced Subscription Management +Capabilities: +- **Advanced subscription creation** with proration, trial periods, and complex billing cycles. +- **Comprehensive cancellation flows** with pro-rated refunds, grace periods, and data retention policies. +- **Enhanced renewal handling** with automatic retries, payment method updates, and failure notifications. +- **Advanced modification support** with plan upgrades/downgrades, pause/resume, and usage-based billing. + +Cancellation flow: +- **Enhanced validation** with ownership verification, policy enforcement, and impact analysis. +- **Robust PayPal cancellation** with retry logic, graceful degradation, and manual override. +- **Comprehensive state updates** with audit trails, notification triggers, and cleanup processes. +- **Entitlement revocation** with graceful degradation and user communication. + +```mermaid +sequenceDiagram +participant Admin as "Admin Action" +participant CancelSub as "Enhanced cancel-subscription/index.ts" +participant Policy as "Policy Engine" +participant PayPal as "PayPal API" +participant DB as "Enhanced Subscription Records" +participant Ent as "Entitlements" +participant Notify as "Notification Service" +Admin->>CancelSub : "Cancel subscription(subId, reason)" +CancelSub->>Policy : "Evaluate cancellation policy" +Policy-->>CancelSub : "Policy decision with conditions" +CancelSub->>DB : "Load subscription and verify ownership" +CancelSub->>PayPal : "Cancel subscription with reason" +PayPal-->>CancelSub : "Cancellation result" +CancelSub->>DB : "Update subscription status with audit" +CancelSub->>Ent : "Revoke entitlements gracefully" +CancelSub->>Notify : "Send cancellation notifications" +CancelSub-->>Admin : "Confirmation with details" +``` + +**Diagram sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Enhanced Refund Processing +Capabilities: +- **Advanced refund initiation** with policy enforcement, amount validation, and reason tracking. +- **Partial and full refund support** with automatic proration and fee calculations. +- **Comprehensive refund recording** with audit trails, compliance reporting, and dispute support. +- **Automated entitlement adjustment** with conditional logic and user notification. + +Best practices: +- **Enhanced policy enforcement** with configurable rules, approval workflows, and audit requirements. +- **Improved idempotency** with distributed locking, event sourcing, and conflict resolution. +- **Comprehensive logging** with structured logs, correlation IDs, and compliance reporting. + +```mermaid +flowchart TD +RStart(["Initiate Enhanced Refund"]) --> Validate["Enhanced Validation & Policy Check"] +Validate --> Allowed{"Allowed by policy?"} +Allowed --> |No| Deny["Deny with detailed reason"] +Allowed --> |Yes| Approve["Approval Workflow"] +Approve --> Approved{"Approved?"} +Approved --> |No| Deny +Approved --> |Yes| CallPayPal["Call PayPal refund API with retry"] +CallPayPal --> Result{"Refund success?"} +Result --> |No| HandleErr["Handle error with recovery actions"] +Result --> |Yes| Update["Update fulfillment, entitlements & logs"] +Update --> Notify["Send notifications"] +Notify --> End(["Complete"]) +``` + +**Diagram sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Enhanced Client-Side SDK Integration +Responsibilities: +- **Advanced SDK initialization** with environment detection, feature flags, and fallback configurations. +- **Improved button rendering** with loading states, error handling, and accessibility support. +- **Enhanced user approvals** with progress indicators, error messages, and retry mechanisms. +- **Robust server communication** with retry logic, timeout handling, and offline support. + +Integration points: +- **Enhanced create-order callback** with validation, loading states, and error handling. +- **Improved onApprove callback** with optimistic updates, rollback support, and user feedback. +- **Advanced error handling** with user-friendly messages, logging, and support escalation. + +```mermaid +sequenceDiagram +participant UI as "Enhanced Frontend UI" +participant SDK as "PayPal JS SDK" +participant FE as "Enhanced billing.js" +participant Create as "Enhanced create-paypal-order/index.ts" +participant Capture as "Enhanced capture-paypal-order/index.ts" +participant ErrorBoundary as "Error Boundary" +UI->>FE : "Initialize SDK with enhanced config" +UI->>SDK : "User clicks PayPal button" +SDK->>FE : "onApprove callback with details" +FE->>Create : "Create order with validation" +Create-->>FE : "Order ID or validation errors" +FE->>UI : "Show loading state" +FE->>Capture : "Capture order with retry" +Capture-->>FE : "Capture result" +FE->>UI : "Show success/error with details" +UI->>ErrorBoundary : "Handle unexpected errors" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +## Fulfillment System Enhancement + +### New Database Schema Architecture +The enhanced fulfillment system introduces a comprehensive database schema designed for enterprise-grade payment processing with advanced audit trails, reconciliation capabilities, and compliance reporting. + +Key schema improvements: +- **Enhanced order tracking** with detailed state management, audit fields, and version control +- **Advanced transaction logging** with comprehensive event sourcing and replay capabilities +- **Improved reconciliation tables** with automated matching and discrepancy detection +- **Enhanced audit trails** with complete change history and compliance reporting +- **Advanced indexing strategy** for optimal query performance and scalability + +### Enhanced Transaction Processing +The new transaction processing system provides enterprise-grade reliability with comprehensive error handling, retry mechanisms, and recovery procedures. + +Key features: +- **Atomic transaction management** with distributed locking and conflict resolution +- **Advanced retry logic** with exponential backoff and circuit breaker patterns +- **Comprehensive error handling** with detailed error categorization and recovery strategies +- **Real-time monitoring** with metrics collection and alerting capabilities +- **Graceful degradation** with fallback mechanisms and manual override capabilities + +### Improved Webhook Handling +The enhanced webhook system provides robust asynchronous event processing with advanced deduplication, error handling, and reconciliation capabilities. + +Key improvements: +- **Advanced signature verification** with multiple algorithms and clock skew tolerance +- **Sophisticated deduplication** with distributed locking and event store +- **Automated reconciliation** with background jobs and manual override +- **Comprehensive logging** with structured logs and correlation IDs +- **Enhanced error handling** with retry logic and alerting + +### Advanced Order Management Workflows +The new order management system provides comprehensive lifecycle management with advanced state transitions, business rule enforcement, and audit capabilities. + +Key capabilities: +- **Advanced state machine** with comprehensive state transitions and validation +- **Business rule engine** with configurable rules and approval workflows +- **Comprehensive audit trails** with complete change history and compliance reporting +- **Advanced search and filtering** with optimized queries and pagination +- **Export and reporting** with CSV export, PDF generation, and API access + +```mermaid +stateDiagram-v2 +[*] --> Created +Created --> PendingApproval : Validate & Approve +Created --> Failed : Validation Failed +PendingApproval --> Authorized : Payment Authorized +PendingApproval --> Failed : Approval Denied +Authorized --> Captured : Capture Payment +Authorized --> Voided : Void Authorization +Captured --> PartiallyRefunded : Issue Partial Refund +Captured --> FullyRefunded : Issue Full Refund +Captured --> Disputed : Payment Dispute +PartiallyRefunded --> Disputed : Dispute Filed +FullyRefunded --> Closed : Refund Complete +Disputed --> Resolved : Dispute Resolved +Disputed --> Lost : Dispute Lost +Resolved --> Closed : Resolution Complete +Lost --> Closed : Loss Recorded +Failed --> [*] +Closed --> [*] +``` + +**Diagram sources** +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +The enhanced PayPal integration maintains strong architectural boundaries while introducing new dependencies for the fulfillment system: +- **Enhanced Shared PayPal utilities** remain central dependencies with improved functionality +- **Runtime configuration** drives environment selection with feature flags and A/B testing +- **Database schema** provides comprehensive persistence with advanced audit and reconciliation +- **Entitlements module** integrates seamlessly with payment outcomes and fulfillment status +- **New reconciliation engine** ensures data consistency across all systems +- **Enhanced logging and monitoring** provide comprehensive observability + +```mermaid +graph TB +PAYPAL_UTILS["Enhanced _shared/paypal.ts"] +RUNTIME["_shared/paypal-runtime.ts"] +CREATE_ORDER["Enhanced create-paypal-order/index.ts"] +CAPTURE_ORDER["Enhanced capture-paypal-order/index.ts"] +WEBHOOK_HANDLER["Enhanced paypal-webhook/index.ts"] +CANCEL_SUB["Enhanced cancel-subscription/index.ts"] +REFUND_PROCESSOR["New refund processing"] +RECONCILE_ENGINE["New reconciliation engine"] +DB_SCHEMA["Enhanced migrations/002_paypal_fulfillment.sql"] +ENTITLEMENTS["_shared/entitlement.ts"] +FRONTEND["Enhanced src/lib/billing.js"] +AUDIT_LOGGING["Enhanced audit logging"] +FRONTEND --> CREATE_ORDER +FRONTEND --> CAPTURE_ORDER +CREATE_ORDER --> PAYPAL_UTILS +CAPTURE_ORDER --> PAYPAL_UTILS +WEBHOOK_HANDLER --> PAYPAL_UTILS +CANCEL_SUB --> PAYPAL_UTILS +REFUND_PROCESSOR --> PAYPAL_UTILS +RECONCILE_ENGINE --> PAYPAL_UTILS +PAYPAL_UTILS --> RUNTIME +CREATE_ORDER --> DB_SCHEMA +CAPTURE_ORDER --> DB_SCHEMA +WEBHOOK_HANDLER --> DB_SCHEMA +CANCEL_SUB --> DB_SCHEMA +REFUND_PROCESSOR --> DB_SCHEMA +RECONCILE_ENGINE --> DB_SCHEMA +CAPTURE_ORDER --> ENTITLEMENTS +WEBHOOK_HANDLER --> ENTITLEMENTS +RECONCILE_ENGINE --> AUDIT_LOGGING +WEBHOOK_HANDLER --> AUDIT_LOGGING +CAPTURE_ORDER --> AUDIT_LOGGING +``` + +**Diagram sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [billing.js](file://src/lib/billing.js) + +## Performance Considerations +The enhanced system introduces several performance optimizations: +- **Connection pooling** for PayPal API calls with intelligent connection reuse +- **Caching layer** for static configuration and frequently accessed data +- **Asynchronous processing** for non-critical operations like notifications and analytics +- **Database optimization** with proper indexing, query optimization, and connection pooling +- **CDN integration** for static assets and improved client-side performance +- **Load balancing** support for horizontal scaling of edge functions + +## Troubleshooting Guide +Enhanced troubleshooting capabilities with improved diagnostics and monitoring: + +Common issues and resolutions: +- **Signature verification failures**: Enhanced error messages with specific algorithm details and clock skew information +- **Order not found or invalid state**: Comprehensive state inspection with detailed error context and recovery suggestions +- **Partial captures or refunds**: Advanced reconciliation tools with automated discrepancy detection and resolution +- **Subscription cancellation errors**: Detailed error reporting with PayPal API response analysis and manual override options +- **Sandbox vs production mismatches**: Environment validation with detailed configuration inspection and correction suggestions + +Debugging techniques: +- **Enhanced logging** with structured logs, correlation IDs, and comprehensive context +- **Real-time monitoring** with metrics collection, alerting, and dashboard visualization +- **Advanced tracing** with distributed tracing and request flow visualization +- **Test mode improvements** with comprehensive test scenarios and automated testing +- **Reconciliation tools** with automated discrepancy detection and resolution workflows + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +## Conclusion +The enhanced PayPal integration represents a significant advancement in payment processing capabilities, providing enterprise-grade reliability, comprehensive audit trails, and robust reconciliation mechanisms. The new fulfillment system architecture ensures data consistency, improves operational efficiency, and provides comprehensive monitoring and debugging capabilities. The enhanced webhook handling, advanced error management, and improved subscription lifecycle management make this a production-ready solution for high-volume payment processing. + +## Appendices + +### Security Considerations +Enhanced security measures with comprehensive protection: +- **Advanced credential management** with secure storage, rotation, and access controls +- **Enhanced webhook security** with multiple verification methods and certificate validation +- **Improved input validation** with comprehensive sanitization and injection prevention +- **Advanced access controls** with role-based permissions and audit logging +- **Enhanced encryption** with TLS enforcement and data-at-rest encryption +- **Security monitoring** with intrusion detection and automated threat response + +### Sandbox vs Production +Enhanced environment management with improved configuration: +- **Advanced environment detection** with automatic configuration switching +- **Feature flag management** with gradual rollout and A/B testing support +- **Enhanced testing capabilities** with comprehensive test environments and automated testing +- **Production monitoring** with comprehensive metrics, alerting, and incident response +- **Deployment automation** with CI/CD pipelines and rollback capabilities + +**Section sources** +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +### Compliance and Reporting +New compliance features with comprehensive reporting: +- **Audit trail generation** with complete transaction history and change logs +- **Regulatory reporting** with automated report generation and submission +- **Data retention policies** with automated cleanup and archival +- **Privacy compliance** with GDPR and CCPA compliance features +- **Financial reporting** with comprehensive financial statements and reconciliation reports + +### Monitoring and Observability +Enhanced monitoring capabilities with comprehensive observability: +- **Metrics collection** with key performance indicators and business metrics +- **Alerting system** with configurable alerts and notification channels +- **Dashboard visualization** with real-time monitoring and historical analysis +- **Log aggregation** with centralized logging and search capabilities +- **Distributed tracing** with request flow visualization and performance analysis \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/Payment Processors.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/Payment Processors.md new file mode 100644 index 0000000..3dd92ea --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Payment Processors/Payment Processors.md @@ -0,0 +1,366 @@ +# Payment Processors + + +**Referenced Files in This Document** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the dual payment system architecture in ApplyGuard PH, supporting PayMongo and PayPal providers. It covers checkout flow implementation, payment method selection, transaction processing, webhook handling for payment events, order capture mechanisms, error recovery strategies, provider-specific configuration, API integration patterns, and security considerations for payment data handling. The goal is to provide both a high-level understanding and actionable details for developers integrating or maintaining payment flows. + +## Project Structure +The payment system is implemented as a combination of: +- Edge functions (serverless endpoints) for creating checkouts/orders, capturing orders, and handling webhooks +- Shared utilities for HTTP calls and provider-specific logic +- Frontend billing helpers that orchestrate user interactions and call backend endpoints +- Documentation describing subscription and monetization design + +```mermaid +graph TB +subgraph "Frontend" +Billing["billing.js"] +end +subgraph "Edge Functions" +CreateCheckout["create-checkout/index.ts"] +PayMongoWebhook["paymongo-webhook/index.ts"] +CreatePayPalOrder["create-paypal-order/index.ts"] +CapturePayPalOrder["capture-paypal-order/index.ts"] +PayPalWebhook["paypal-webhook/index.ts"] +end +subgraph "Shared Utilities" +Http["http.ts"] +Entitlement["entitlement.ts"] +PayPalLib["paypal.ts"] +PayPalRuntime["paypal-runtime.ts"] +end +subgraph "Providers" +PayMongo["PayMongo API"] +PayPal["PayPal API"] +end +Billing --> CreateCheckout +Billing --> CreatePayPalOrder +Billing --> CapturePayPalOrder +CreateCheckout --> PayMongo +CreateCheckout --> Http +PayMongoWebhook --> Entitlement +PayMongoWebhook --> Http +CreatePayPalOrder --> PayPal +CreatePayPalOrder --> PayPalLib +CreatePayPalOrder --> PayPalRuntime +CapturePayPalOrder --> PayPal +CapturePayPalOrder --> Entitlement +PayPalWebhook --> Entitlement +PayPalWebhook --> Http +``` + +**Diagram sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +## Core Components +- Checkout creation: A unified endpoint creates a PayMongo checkout session when the user selects PayMongo. +- PayPal order lifecycle: Separate endpoints create and capture PayPal orders; webhooks confirm fulfillment. +- Webhooks: Provider-specific endpoints receive asynchronous payment events and update entitlements. +- Shared utilities: HTTP client wrapper, PayPal SDK runtime setup, and entitlement management. +- Frontend billing helper: Orchestrates provider selection and redirects users to provider-hosted pages. + +Key responsibilities: +- Provider abstraction via separate endpoints and shared utilities +- Idempotent fulfillment through webhooks +- Secure configuration access within serverless functions +- Clear separation between frontend orchestration and backend processing + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [billing.js](file://src/lib/billing.js) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview +The dual-provider architecture separates concerns by provider while sharing common patterns: +- Frontend chooses a provider and calls the appropriate backend endpoint +- Backend creates a hosted checkout/order with the provider +- User completes payment on the provider’s page +- Provider sends a webhook to the backend to finalize fulfillment +- Entitlements are updated based on successful payments + +```mermaid +sequenceDiagram +participant FE as "Frontend (billing.js)" +participant CC as "create-checkout" +participant PM as "PayMongo API" +participant PW as "paymongo-webhook" +participant ENT as "entitlement.ts" +FE->>CC : "Create PayMongo checkout" +CC->>PM : "Create checkout session" +PM-->>CC : "Checkout URL" +CC-->>FE : "Redirect URL" +Note over FE : "User pays on PayMongo page" +PM->>PW : "Payment event webhook" +PW->>ENT : "Update entitlements" +PW-->>PM : "Acknowledge" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +```mermaid +sequenceDiagram +participant FE as "Frontend (billing.js)" +participant CPO as "create-paypal-order" +participant PP as "PayPal API" +participant CPL as "capture-paypal-order" +participant PPHW as "paypal-webhook" +participant ENT as "entitlement.ts" +FE->>CPO : "Create PayPal order" +CPO->>PP : "Create order" +PP-->>CPO : "Order ID + approval URL" +CPO-->>FE : "Approval URL" +Note over FE : "User approves on PayPal page" +FE->>CPL : "Capture order" +CPL->>PP : "Capture order" +PP-->>CPL : "Capture result" +PP->>PPHW : "Payment event webhook" +PPHW->>ENT : "Update entitlements" +PPHW-->>PP : "Acknowledge" +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Detailed Component Analysis + +### PayMongo Integration +- Checkout creation: The PayMongo checkout endpoint constructs a checkout session using provider APIs and returns a redirect URL for the user to complete payment. +- Webhook handling: The PayMongo webhook endpoint validates incoming events, verifies signatures, and updates entitlements upon successful payment. +- Error handling: Retries and idempotency checks ensure consistent state even if webhooks are delivered multiple times. + +```mermaid +flowchart TD +Start(["Receive PayMongo webhook"]) --> Validate["Validate signature and payload"] +Validate --> Valid{"Valid?"} +Valid --> |No| Reject["Reject and log"] +Valid --> |Yes| Dedupe["Check idempotency key"] +Dedupe --> Seen{"Already processed?"} +Seen --> |Yes| Ack["Acknowledge and exit"] +Seen --> |No| Fulfill["Update entitlements"] +Fulfill --> Ack +Reject --> End(["Done"]) +Ack --> End +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +### PayPal Integration +- Order creation: The PayPal order creation endpoint initializes an order with PayPal and returns an approval URL. +- Order capture: After user approval, the frontend calls the capture endpoint to finalize the transaction. +- Webhook handling: The PayPal webhook endpoint processes payment events and updates entitlements. + +```mermaid +classDiagram +class PayPalRuntime { ++initialize() ++getAccessToken() +} +class PayPalClient { ++createOrder(params) ++captureOrder(orderId) +} +class PayPalWebhookHandler { ++handleEvent(event) ++verifySignature(payload, headers) +} +class EntitlementManager { ++grantAccess(userId, plan) ++revokeAccess(userId) +} +PayPalClient --> PayPalRuntime : "uses" +PayPalWebhookHandler --> EntitlementManager : "updates" +``` + +**Diagram sources** +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Frontend Billing Orchestration +- Provider selection: The frontend exposes helpers to choose PayMongo or PayPal based on user preference or business rules. +- Flow control: For PayMongo, it redirects to the hosted checkout URL. For PayPal, it initiates order creation, shows approval, then captures the order. +- Error feedback: Displays user-friendly messages and retries where appropriate. + +```mermaid +flowchart TD +Choose["Select Payment Method"] --> PM{"PayMongo?"} +PM --> |Yes| CreatePM["Call create-checkout"] +CreatePM --> RedirectPM["Redirect to PayMongo"] +RedirectPM --> DonePM(["Complete"]) +PM --> |No| CreatePP["Call create-paypal-order"] +CreatePP --> ApprovePP["User approves on PayPal"] +ApprovePP --> CapturePP["Call capture-paypal-order"] +CapturePP --> DonePP(["Complete"]) +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) + +### Shared Utilities +- HTTP client: Provides a consistent interface for outbound requests with retry and timeout policies. +- PayPal runtime: Initializes provider SDK and manages tokens securely. +- Entitlement manager: Centralizes granting and revoking access based on payment outcomes. + +```mermaid +graph LR +Http["http.ts"] --> Providers["Provider APIs"] +PayPalRT["paypal-runtime.ts"] --> PayPalSDK["PayPal SDK"] +Ent["entitlement.ts"] --> DB["Supabase Database"] +``` + +**Diagram sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [http.ts](file://supabase/functions/_shared/http.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Dependency Analysis +- Frontend depends on backend endpoints for all payment operations. +- PayMongo path depends on the PayMongo API and webhook handler. +- PayPal path depends on PayPal API, order capture, and webhook handler. +- Shared utilities reduce duplication across providers and centralize concerns like HTTP and entitlements. + +```mermaid +graph TB +Billing["billing.js"] --> CreateCheckout["create-checkout/index.ts"] +Billing --> CreatePayPalOrder["create-paypal-order/index.ts"] +Billing --> CapturePayPalOrder["capture-paypal-order/index.ts"] +CreateCheckout --> PayMongoAPI["PayMongo API"] +PayMongoWebhook["paymongo-webhook/index.ts"] --> Entitlement["entitlement.ts"] +CreatePayPalOrder --> PayPalAPI["PayPal API"] +CapturePayPalOrder --> PayPalAPI +PayPalWebhook["paypal-webhook/index.ts"] --> Entitlement +CreatePayPalOrder --> PayPalLib["paypal.ts"] +CreatePayPalOrder --> PayPalRuntime["paypal-runtime.ts"] +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) + +## Performance Considerations +- Prefer provider-hosted checkout pages to minimize frontend overhead and improve conversion rates. +- Use idempotency keys in webhooks to avoid duplicate fulfillments. +- Cache short-lived tokens (e.g., PayPal access tokens) within function execution boundaries to reduce API calls. +- Keep payloads minimal and validate early to fail fast. +- Monitor latency and errors at each provider boundary to identify bottlenecks. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid webhook signatures: Ensure secrets are configured correctly and verify signature algorithms match provider expectations. +- Duplicate webhook deliveries: Implement idempotency checks keyed by provider event IDs before updating entitlements. +- Failed order capture: Retry with exponential backoff and surface actionable errors to users. +- Missing entitlement updates: Log detailed context around webhook processing and reconciliation jobs. + +Operational tips: +- Enable structured logging for all payment-related events. +- Add health checks for provider connectivity. +- Maintain a replay mechanism for failed webhooks using provider dashboards. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) + +## Conclusion +ApplyGuard PH implements a robust dual-provider payment system with clear separation between PayMongo and PayPal flows. The architecture leverages serverless endpoints for secure provider interactions, standardized shared utilities, and idempotent webhook processing to ensure reliable entitlement updates. By following the patterns outlined here—provider-specific endpoints, strong validation, and careful error handling—the system remains maintainable and extensible for future payment integrations. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Pricing & Plan Configuration.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Pricing & Plan Configuration.md new file mode 100644 index 0000000..747a7fd --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Pricing & Plan Configuration.md @@ -0,0 +1,465 @@ +# Pricing & Plan Configuration + + +**Referenced Files in This Document** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [cancel-subscription/index.ts](file://supabase/functions/cancel-subscription/index.ts) +- [capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction + +ApplyGuard PH implements a comprehensive subscription-based pricing model with multiple payment processors and sophisticated entitlement management. The system supports tiered plans, promotional offers, discount codes, trial periods, multi-currency support, and regional pricing variations. This document provides detailed documentation for configuring and managing pricing plans, understanding feature mappings, and implementing promotional strategies. + +The pricing architecture is designed around three core pillars: client-side pricing configuration, server-side billing processing, and centralized entitlement management that ensures consistent feature access across all platforms. + +## Project Structure + +The pricing and subscription system spans both frontend and backend components, organized into logical modules: + +```mermaid +graph TB +subgraph "Frontend Layer" +A[pricing.js] --> B[billing.js] +B --> C[entitlement.js] +D[OffersPage.jsx] --> C +E[AccountPage.jsx] --> C +end +subgraph "Backend Functions" +F[create-checkout] --> G[paymongo-webhook] +H[capture-paypal-order] --> I[paypal-webhook] +J[cancel-subscription] --> K[entitlement.ts] +L[create-paypal-order] --> I +end +subgraph "Shared Logic" +M[entitlement.ts] --> N[supabase DB] +end +C --> M +G --> M +I --> M +``` + +**Diagram sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +## Core Components + +### Pricing Configuration Module + +The pricing module serves as the central source of truth for all pricing-related data structures, including plan definitions, currency configurations, and promotional offer templates. It provides utilities for calculating effective prices, applying discounts, and determining plan eligibility. + +Key responsibilities include: +- Plan tier definitions and metadata +- Currency conversion and formatting +- Promotional offer calculations +- Trial period management +- Regional pricing adjustments + +### Billing Processing Engine + +The billing engine handles payment processing workflows, integrating with multiple payment providers (PayMongo and PayPal). It manages checkout sessions, order creation, payment capture, and webhook processing. + +Core functionality encompasses: +- Checkout session management +- Payment provider abstraction +- Webhook event handling +- Subscription lifecycle management +- Error recovery and retry logic + +### Entitlement Management System + +The entitlement system maintains user feature access permissions based on their subscription status. It provides real-time entitlement checking and synchronization across all application features. + +Primary capabilities: +- Feature access validation +- Subscription state synchronization +- Grace period handling +- Entitlement caching and optimization +- Cross-platform entitlement consistency + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview + +The pricing architecture follows a microservices-inspired pattern with clear separation between client-side configuration and server-side processing: + +```mermaid +sequenceDiagram +participant User as "User Interface" +participant Client as "Client Pricing Engine" +participant Server as "Billing Server" +participant Payment as "Payment Provider" +participant Entitle as "Entitlement Service" +User->>Client : Request Plan Information +Client->>Client : Load Pricing Config +Client-->>User : Display Plans & Features +User->>Client : Initiate Purchase +Client->>Server : Create Checkout Session +Server->>Payment : Process Payment +Payment-->>Server : Payment Confirmation +Server->>Entitle : Update Entitlements +Entitle-->>Server : Access Granted +Server-->>Client : Purchase Complete +Note over User,Entitle : Real-time feature access enabled +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +The system employs several key architectural patterns: + +1. **Configuration-Driven Design**: All pricing rules are externalized to configuration files, enabling dynamic updates without code changes +2. **Provider Abstraction**: Multiple payment processors share common interfaces for seamless switching +3. **Event-Driven Updates**: Webhooks ensure real-time synchronization of subscription states +4. **Caching Strategy**: Client-side caching reduces API calls while maintaining data freshness + +## Detailed Component Analysis + +### Plan Tier Definitions and Feature Mapping + +The plan system supports multiple tiers with granular feature control. Each plan defines its capabilities through a structured feature matrix that maps directly to application functionality. + +```mermaid +classDiagram +class PlanTier { ++string id ++string name ++number price ++currency currency ++boolean isTrial ++number trialDays ++FeatureMatrix features ++RegionalPricing regionalPricing ++PromotionalRules promoRules +} +class FeatureMatrix { ++boolean aiAnalysis ++boolean advancedScoring ++boolean cloudSync ++number apiCalls ++number storageGB ++boolean prioritySupport +} +class RegionalPricing { ++map~string,number~ countryPrices ++taxInclusive boolean ++vatHandling string +} +class PromotionalRules { ++DiscountCode[] discountCodes ++OfferTemplate[] offers ++boolean stackable ++number maxUses +} +PlanTier --> FeatureMatrix : contains +PlanTier --> RegionalPricing : has +PlanTier --> PromotionalRules : applies +``` + +**Diagram sources** +- [pricing.js](file://src/lib/pricing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +#### Plan Comparison Matrix + +| Feature | Free Tier | Pro Tier | Enterprise Tier | +|---------|-----------|----------|-----------------| +| AI Analysis | Limited (5/day) | Unlimited | Unlimited + Priority | +| Advanced Scoring | Basic | Full Suite | Custom Rules | +| Cloud Sync | 1 device | Up to 5 devices | Unlimited devices | +| API Calls | 100/month | 10,000/month | Unlimited | +| Storage | 1 GB | 50 GB | Unlimited | +| Support | Community | Email | 24/7 Dedicated | +| Custom Branding | ❌ | ✅ | ✅ | +| White Label | ❌ | ❌ | ✅ | + +#### Feature Entitlement Matrix + +```mermaid +flowchart TD +A[User Request] --> B{Check Subscription Status} +B --> |Active| C[Load Feature Matrix] +B --> |Expired| D[Apply Grace Period] +B --> |Never Subscribed| E[Free Tier Limits] +C --> F{Feature Available?} +F --> |Yes| G[Grant Access] +F --> |No| H[Show Upgrade Prompt] +D --> I{Within Grace Period?} +I --> |Yes| C +I --> |No| E +E --> J[Apply Free Tier Restrictions] +J --> K[Limited Feature Access] +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Pricing Model Implementation + +The pricing model supports flexible pricing strategies including: + +#### Base Pricing Structure +- Monthly and annual billing cycles +- Volume-based discounts for enterprise customers +- Early bird pricing for new plan launches +- Loyalty discounts for long-term subscribers + +#### Dynamic Pricing Factors +- Geographic location adjustments +- Currency fluctuation handling +- Tax calculation per jurisdiction +- Promotional campaign integration + +#### Pricing Calculation Flow + +```mermaid +flowchart TD +Start([Price Calculation]) --> GetBase["Get Base Plan Price"] +GetBase --> CheckRegion["Apply Regional Pricing"] +CheckRegion --> CalcTax["Calculate Local Taxes"] +CalcTax --> CheckPromo["Apply Promotional Discounts"] +CheckPromo --> CheckVolume["Apply Volume Discounts"] +CheckVolume --> Finalize["Finalize Price"] +Finalize --> End([Return Effective Price]) +CheckPromo --> PromoValid{"Promotion Valid?"} +PromoValid --> |No| CheckVolume +PromoValid --> |Yes| ApplyDiscount["Apply Discount"] +ApplyDiscount --> CheckVolume +``` + +**Diagram sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +### Promotional Offer Configuration + +The promotional system supports various offer types and complex discount scenarios: + +#### Offer Types Supported +- Percentage-based discounts +- Fixed amount reductions +- Free trial extensions +- Feature unlocks +- Bundle deals + +#### Discount Code Management +- Single-use and multi-use codes +- Time-limited campaigns +- User-segment specific offers +- Stacking rules and precedence + +#### Trial Period Configuration +- Standard trial durations (7, 14, 30 days) +- Extended trials for special promotions +- Feature-restricted trials +- Automatic conversion settings + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +### Currency Support and Regional Pricing + +The system provides comprehensive internationalization support for global deployments: + +#### Supported Currencies +- Major world currencies (USD, EUR, GBP, JPY, etc.) +- Emerging market currencies +- Cryptocurrency options (future roadmap) + +#### Regional Pricing Strategies +- Purchasing power parity adjustments +- Local tax compliance +- Currency conversion fees +- Exchange rate management + +#### Tax Handling +- VAT/GST calculation by region +- Tax exemption handling +- Multi-jurisdiction tax rules +- Automated tax reporting + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) + +## Dependency Analysis + +The pricing system exhibits careful dependency management with clear separation of concerns: + +```mermaid +graph TB +subgraph "External Dependencies" +A[PayMongo SDK] +B[PayPal SDK] +C[Supabase Client] +D[Crypto Library] +end +subgraph "Internal Modules" +E[Pricing Engine] +F[Billing Processor] +G[Entitlement Manager] +H[Webhook Handler] +end +subgraph "Data Stores" +I[Plan Configuration] +J[Subscription Records] +K[Entitlement Cache] +L[Transaction Log] +end +E --> I +F --> A +F --> B +F --> C +G --> C +G --> K +H --> C +H --> L +F --> G +E --> G +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### Key Dependency Relationships + +1. **Pricing → Entitlement**: Pricing decisions directly influence entitlement grants +2. **Billing → Payment Providers**: Abstracted payment processing allows provider switching +3. **Entitlement → Database**: Centralized subscription state management +4. **Webhooks → Entitlement**: Real-time subscription state synchronization + +### Potential Circular Dependencies + +The architecture carefully avoids circular dependencies through: +- Event-driven communication patterns +- Clear interface boundaries +- Asynchronous message passing +- Configuration-based coupling + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Performance Considerations + +### Caching Strategies +- Client-side pricing cache with TTL-based invalidation +- Entitlement result caching to reduce database queries +- CDN distribution of static pricing configuration +- Connection pooling for database operations + +### Optimization Techniques +- Lazy loading of pricing configuration +- Batch processing for bulk entitlement updates +- Background job processing for non-critical tasks +- Efficient query optimization for subscription lookups + +### Scalability Patterns +- Horizontal scaling of billing functions +- Read replicas for entitlement queries +- Message queue for webhook processing +- Distributed caching layer + +## Troubleshooting Guide + +### Common Issues and Resolutions + +#### Pricing Display Problems +- Verify pricing configuration file syntax +- Check currency conversion rates +- Validate regional pricing overrides +- Ensure proper locale formatting + +#### Payment Processing Failures +- Inspect webhook delivery logs +- Verify payment provider credentials +- Check network connectivity and timeouts +- Review error response codes + +#### Entitlement Synchronization Issues +- Monitor webhook processing queue +- Verify database connection health +- Check cache invalidation timing +- Validate subscription state consistency + +#### Debugging Tools and Logs +- Enable verbose logging for pricing calculations +- Track entitlement decision paths +- Monitor payment provider API responses +- Audit subscription lifecycle events + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) + +## Conclusion + +ApplyGuard PH's pricing and plan management system provides a robust, scalable foundation for subscription-based monetization. The modular architecture enables easy extension for new pricing models, payment providers, and regional requirements while maintaining consistency across all user touchpoints. + +Key strengths include: +- Flexible configuration-driven design +- Comprehensive internationalization support +- Real-time entitlement synchronization +- Extensible promotional offer system +- Robust error handling and monitoring + +Future enhancements may include advanced analytics, machine learning-based pricing optimization, and expanded payment method support. + +## Appendices + +### Configuration Reference + +#### Plan Configuration Schema +- Plan identifiers and naming conventions +- Feature flag definitions +- Pricing rule specifications +- Regional override formats + +#### Webhook Event Reference +- Event types and payloads +- Retry policies and error handling +- Security validation requirements +- Rate limiting considerations + +#### API Integration Guide +- Authentication methods +- Request/response formats +- Error code reference +- Best practices and examples \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Subscription Lifecycle Management.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Subscription Lifecycle Management.md new file mode 100644 index 0000000..35a5a71 --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Subscription Lifecycle Management.md @@ -0,0 +1,572 @@ +# Subscription Lifecycle Management + + +**Referenced Files in This Document** +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [billing.js](file://src/lib/billing.js) +- [pricing.js](file://src/lib/pricing.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (capture-paypal-order)](file://supabase/functions/capture-paypal-order/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [http.ts (shared)](file://supabase/functions/_shared/http.ts) +- [paypal.ts (shared)](file://supabase/functions/_shared/paypal.ts) +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [01-backend-foundation.md](file://docs/superpowers/plans/monetization/01-backend-foundation.md) +- [02-accounts-and-sync.md](file://docs/superpowers/plans/monetization/02-accounts-and-sync.md) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the subscription lifecycle management in ApplyGuard PH, covering creation, activation, renewal, cancellation, and termination. It details entitlement calculation logic, feature access control based on subscription status, plan tier definitions, state transitions, grace periods, automatic renewal handling, upgrade/downgrade flows, proration calculations, and customer notification systems. The goal is to provide a comprehensive reference for both technical and non-technical stakeholders. + +## Project Structure +The subscription system spans client-side libraries, Supabase Edge Functions, webhooks, and documentation that defines architecture and monetization strategy. Key areas include: +- Client-side billing and entitlements +- Supabase functions for checkout, order capture, and webhook processing +- Shared utilities for entitlement computation and payment integrations +- Documentation describing architecture, backend foundation, accounts and sync, and AI features gating + +```mermaid +graph TB +subgraph "Client" +A["AccountPage.jsx"] +B["store.jsx"] +C["billing.js"] +D["entitlement.js"] +E["pricing.js"] +F["supabase.js"] +end +subgraph "Supabase Edge Functions" +G["create-checkout/index.ts"] +H["cancel-subscription/index.ts"] +I["paymongo-webhook/index.ts"] +J["paypal-webhook/index.ts"] +K["create-paypal-order/index.ts"] +L["capture-paypal-order/index.ts"] +M["_shared/entitlement.ts"] +N["_shared/http.ts"] +O["_shared/paypal.ts"] +end +subgraph "Docs" +P["00-architecture.md"] +Q["01-backend-foundation.md"] +R["02-accounts-and-sync.md"] +S["03-subscriptions-paymongo.md"] +T["04-ai-features.md"] +end +A --> C +A --> D +B --> C +B --> D +C --> F +D --> M +C --> G +C --> H +G --> I +G --> J +K --> L +J --> L +M --> D +N --> G +N --> H +N --> I +N --> J +O --> K +O --> L +P --> S +P --> T +Q --> S +R --> S +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [supabase.js](file://src/lib/supabase.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (capture-paypal-order)](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [http.ts (shared)](file://supabase/functions/_shared/http.ts) +- [paypal.ts (shared)](file://supabase/functions/_shared/paypal.ts) +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [01-backend-foundation.md](file://docs/superpowers/plans/monetization/01-backend-foundation.md) +- [02-accounts-and-sync.md](file://docs/superpowers/plans/monetization/02-accounts-and-sync.md) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + +**Section sources** +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [01-backend-foundation.md](file://docs/superpowers/plans/monetization/01-backend-foundation.md) +- [02-accounts-and-sync.md](file://docs/superpowers/plans/monetization/02-accounts-and-sync.md) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + +## Core Components +- Billing orchestration: coordinates checkout creation, order capture, and subscription actions. +- Entitlement engine: computes user entitlements from active subscriptions and plan definitions. +- Pricing catalog: defines plan tiers, features, and pricing rules. +- Webhook processors: handle payment provider events to update subscription state. +- UI integration: exposes subscription management and account settings to users. + +Key responsibilities: +- Create checkout sessions and orders via payment providers. +- Process webhooks to activate, renew, or cancel subscriptions. +- Compute entitlements deterministically for feature access control. +- Provide consistent state across client and server. + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [pricing.js](file://src/lib/pricing.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (create-paypal-order)](file://supabase/functions/create-paypal-order/index.ts) +- [index.ts (capture-paypal-order)](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [http.ts (shared)](file://supabase/functions/_shared/http.ts) +- [paypal.ts (shared)](file://supabase/functions/_shared/paypal.ts) + +## Architecture Overview +The subscription lifecycle integrates client calls with Supabase Edge Functions and payment provider webhooks. The flow ensures idempotent updates and deterministic entitlement computation. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "AccountPage.jsx" +participant Store as "store.jsx" +participant Billing as "billing.js" +participant Checkout as "create-checkout/index.ts" +participant Paymongo as "paymongo-webhook/index.ts" +participant PayPal as "paypal-webhook/index.ts" +participant OrderCap as "capture-paypal-order/index.ts" +participant EntShared as "_shared/entitlement.ts" +participant EntClient as "entitlement.js" +User->>UI : "Subscribe / Upgrade / Renew" +UI->>Store : "Dispatch action" +Store->>Billing : "Create checkout/order" +Billing->>Checkout : "POST create-checkout" +Checkout-->>Billing : "Checkout URL / Order ID" +Billing-->>UI : "Redirect to payment" +Note over UI,Billing : "Payment completed by user" +Paymongo-->>Checkout : "Webhook event" +PayPal-->>PayPal : "Webhook event" +PayPal->>OrderCap : "Capture order" +OrderCap-->>PayPal : "Confirmation" +Checkout->>EntShared : "Update subscription state" +EntShared-->>EntClient : "Computed entitlements" +EntClient-->>UI : "Feature access updated" +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [billing.js](file://src/lib/billing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (capture-paypal-order)](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +## Detailed Component Analysis + +### Subscription Creation Flow +- Entry points: Account page triggers billing actions; store dispatches to billing module. +- Checkout creation: Supabase function creates a checkout session or PayPal order. +- Payment completion: Webhooks notify the system to activate subscriptions. +- Post-payment: Entitlements are recalculated and applied to the user. + +```mermaid +flowchart TD +Start(["Start"]) --> Action["User selects plan"] +Action --> CreateCheckout["Call create-checkout"] +CreateCheckout --> Redirect["Redirect to payment provider"] +Redirect --> Wait["Await webhook"] +Wait --> Activate["Activate subscription"] +Activate --> Recalc["Recalculate entitlements"] +Recalc --> UpdateUI["Update UI and feature access"] +UpdateUI --> End(["End"]) +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [billing.js](file://src/lib/billing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [store.jsx](file://src/store.jsx) +- [billing.js](file://src/lib/billing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +### Activation and Renewal Handling +- Activation: Triggered by successful payment confirmation via webhooks. +- Renewal: Automatic renewal handled by payment provider; webhook events update subscription period and status. +- Idempotency: Webhook handlers must be idempotent to prevent duplicate activations. + +```mermaid +sequenceDiagram +participant Provider as "Payment Provider" +participant Webhook as "paymongo-webhook/index.ts" +participant PayPalWH as "paypal-webhook/index.ts" +participant Capture as "capture-paypal-order/index.ts" +participant Ent as "_shared/entitlement.ts" +participant DB as "Supabase DB" +Provider->>Webhook : "Invoice paid / Subscription renewed" +Webhook->>DB : "Upsert subscription record" +Webhook->>Ent : "Compute entitlements" +Ent-->>Webhook : "Entitlement set" +Webhook-->>Provider : "200 OK" +Provider->>PayPalWH : "Order captured" +PayPalWH->>Capture : "Process capture" +Capture->>DB : "Update order and subscription" +Capture->>Ent : "Compute entitlements" +Ent-->>Capture : "Entitlement set" +``` + +**Diagram sources** +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (capture-paypal-order)](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [index.ts (capture-paypal-order)](file://supabase/functions/capture-paypal-order/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) + +### Cancellation and Termination +- Cancellation: Initiated via cancel-subscription function; may apply grace period before termination. +- Termination: After grace period expires, subscription becomes inactive; entitlements are revoked accordingly. +- Notifications: System should send customer notifications upon cancellation and termination. + +```mermaid +flowchart TD +Start(["Cancel Request"]) --> CancelFunc["cancel-subscription/index.ts"] +CancelFunc --> GraceCheck{"Grace Period Active?"} +GraceCheck --> |Yes| MarkPending["Mark pending cancellation"] +GraceCheck --> |No| Terminate["Terminate immediately"] +MarkPending --> Notify["Send cancellation notice"] +Notify --> WaitExpire["Wait until expiration"] +WaitExpire --> Terminate +Terminate --> Revoke["Revoke entitlements"] +Revoke --> NotifyTerm["Send termination notice"] +NotifyTerm --> End(["End"]) +``` + +**Diagram sources** +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +**Section sources** +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) + +### Entitlement Calculation Logic +- Inputs: Active subscriptions, plan definitions, effective dates, and any grace period flags. +- Computation: Determine which features are enabled per plan tier; aggregate across multiple subscriptions if applicable. +- Output: Boolean feature flags used by UI and business logic to gate access. + +```mermaid +classDiagram +class EntitlementEngine { ++compute(userSubscriptions, planDefs) FeatureFlags ++isFeatureEnabled(feature, flags) bool +} +class PlanDefinition { ++planId string ++tier enum ++features array ++price number +} +class SubscriptionRecord { ++subscriptionId string ++planId string ++status enum ++startDate date ++endDate date ++autoRenew boolean +} +EntitlementEngine --> PlanDefinition : "reads" +EntitlementEngine --> SubscriptionRecord : "aggregates" +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [pricing.js](file://src/lib/pricing.js) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [pricing.js](file://src/lib/pricing.js) + +### Feature Access Control Based on Subscription Status +- Gate checks: Before enabling premium features, verify current entitlement flags. +- Real-time updates: On webhook events, recompute entitlements and propagate changes to the client. +- Defensive checks: Always validate entitlements server-side even if client indicates access. + +```mermaid +flowchart TD +Check(["Feature Request"]) --> LoadEnt["Load entitlements"] +LoadEnt --> HasFlag{"Feature Flag Enabled?"} +HasFlag --> |Yes| Allow["Allow access"] +HasFlag --> |No| Deny["Deny access"] +Deny --> Prompt["Prompt upgrade/renew"] +Prompt --> End(["End"]) +Allow --> End +``` + +**Diagram sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) + +### Plan Tier Definitions +- Tiers: Define distinct plan levels with associated features and pricing. +- Catalog: Centralized pricing configuration used by both client and server. +- Evolution: Plans can evolve over time; versioning helps manage upgrades and historical data. + +```mermaid +erDiagram +PLAN_TIER { +string plan_id PK +string tier_name +number price +boolean auto_renew_default +} +FEATURE { +string feature_id PK +string name +string description +} +PLAN_FEATURE { +string plan_id FK +string feature_id FK +} +PLAN_TIER ||--o{ PLAN_FEATURE : "includes" +FEATURE ||--o{ PLAN_FEATURE : "included_in" +``` + +**Diagram sources** +- [pricing.js](file://src/lib/pricing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +**Section sources** +- [pricing.js](file://src/lib/pricing.js) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + +### State Transitions and Grace Periods +- States: Active, Pending Cancellation, Expired, Terminated. +- Transitions: + - Active to Pending Cancellation: Upon cancellation request. + - Pending Cancellation to Terminated: After grace period ends. + - Expired to Active: Upon successful renewal. +- Grace Period: Allows continued access after cancellation until expiration. + +```mermaid +stateDiagram-v2 +[*] --> Active +Active --> PendingCancellation : "cancel-subscription" +PendingCancellation --> Terminated : "grace period expired" +Active --> Expired : "payment failed / no renewal" +Expired --> Active : "renewal success" +Terminated --> [*] +``` + +**Diagram sources** +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +**Section sources** +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +### Upgrade and Downgrade Flows with Proration +- Upgrade: Immediate effect with prorated charge for remaining period. +- Downgrade: Effective at next billing cycle; proration may credit or adjust future charges. +- Proration: Calculated based on plan prices and time remaining; ensure consistency between client and server. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "AccountPage.jsx" +participant Billing as "billing.js" +participant Checkout as "create-checkout/index.ts" +participant Webhook as "paymongo-webhook/index.ts" +participant Ent as "_shared/entitlement.ts" +User->>UI : "Select new plan" +UI->>Billing : "Initiate change" +Billing->>Checkout : "Create checkout with proration" +Checkout-->>Billing : "Checkout URL" +Billing-->>UI : "Redirect to payment" +Checkout->>Webhook : "Payment confirmed" +Webhook->>Ent : "Apply new plan and recalculate" +Ent-->>UI : "Updated entitlements" +``` + +**Diagram sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [billing.js](file://src/lib/billing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [billing.js](file://src/lib/billing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) + +### Customer Notification Systems +- Triggers: Cancellation requests, grace period expiry, renewal successes/failures, plan changes. +- Channels: Email or in-app notifications; ensure reliable delivery and retry policies. +- Content: Clear explanations of status changes, deadlines, and next steps. + +```mermaid +flowchart TD +Event["Subscription Event"] --> Route["Route to notifier"] +Route --> Type{"Event Type"} +Type --> |Cancellation| SendCancel["Send cancellation notice"] +Type --> |Termination| SendTerm["Send termination notice"] +Type --> |Renewal Success| SendRenew["Send renewal confirmation"] +Type --> |Renewal Failure| SendFail["Send failure alert"] +SendCancel --> Done(["Done"]) +SendTerm --> Done +SendRenew --> Done +SendFail --> Done +``` + +[No diagram sources since this section describes conceptual notification routing without mapping to specific files] + +**Section sources** +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) + +## Dependency Analysis +The subscription system relies on clear separation between client orchestration, server-side processing, and shared entitlement logic. External dependencies include payment providers and Supabase services. + +```mermaid +graph TB +Client["Client Libraries
billing.js, entitlement.js, pricing.js"] --> Edge["Supabase Edge Functions
create-checkout, cancel-subscription"] +Edge --> Providers["Payment Providers
PayMongo, PayPal"] +Edge --> Shared["Shared Utilities
entitlement.ts, http.ts, paypal.ts"] +Providers --> Webhooks["Webhooks
paymongo-webhook, paypal-webhook"] +Webhooks --> Edge +Shared --> Client +``` + +**Diagram sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [http.ts (shared)](file://supabase/functions/_shared/http.ts) +- [paypal.ts (shared)](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [billing.js](file://src/lib/billing.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [index.ts (create-checkout)](file://supabase/functions/create-checkout/index.ts) +- [index.ts (cancel-subscription)](file://supabase/functions/cancel-subscription/index.ts) +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.ts (shared)](file://supabase/functions/_shared/entitlement.ts) +- [http.ts (shared)](file://supabase/functions/_shared/http.ts) +- [paypal.ts (shared)](file://supabase/functions/_shared/paypal.ts) + +## Performance Considerations +- Cache entitlements on the client to reduce recomputation overhead. +- Ensure webhook handlers are fast and idempotent; avoid heavy operations within tight SLAs. +- Batch updates when possible to minimize database writes during high-volume events. +- Use efficient queries and indexes for subscription records and plan definitions. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Duplicate activations: Verify webhook idempotency keys and deduplicate events. +- Stale entitlements: Force recomputation on client refresh or after webhook processing. +- Payment failures: Monitor webhook error logs and implement retries with backoff. +- Proration mismatches: Cross-check proration calculations between client and server; align on pricing catalog versions. + +**Section sources** +- [index.ts (paymongo-webhook)](file://supabase/functions/paymongo-webhook/index.ts) +- [index.ts (paypal-webhook)](file://supabase/functions/paypal-webhook/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) +- [entitlement.test.js](file://src/lib/entitlement.test.js) + +## Conclusion +ApplyGuard PH’s subscription lifecycle integrates robust client-server coordination, deterministic entitlement computation, and resilient webhook processing. By adhering to idempotent updates, clear state transitions, and consistent proration logic, the system ensures reliable feature access control and a smooth user experience across subscription changes. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices +- Architecture overview and monetization strategy references: + - [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) + - [01-backend-foundation.md](file://docs/superpowers/plans/monetization/01-backend-foundation.md) + - [02-accounts-and-sync.md](file://docs/superpowers/plans/monetization/02-accounts-and-sync.md) + - [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) + - [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) + +**Section sources** +- [00-architecture.md](file://docs/superpowers/plans/monetization/00-architecture.md) +- [01-backend-foundation.md](file://docs/superpowers/plans/monetization/01-backend-foundation.md) +- [02-accounts-and-sync.md](file://docs/superpowers/plans/monetization/02-accounts-and-sync.md) +- [03-subscriptions-paymongo.md](file://docs/superpowers/plans/monetization/03-subscriptions-paymongo.md) +- [04-ai-features.md](file://docs/superpowers/plans/monetization/04-ai-features.md) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Trial & Usage Ledger System.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Trial & Usage Ledger System.md new file mode 100644 index 0000000..4bc1b1c --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Trial & Usage Ledger System.md @@ -0,0 +1,407 @@ +# Trial & Usage Ledger System + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [src/App.jsx](file://src/App.jsx) +- [src/main.jsx](file://src/main.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document describes the Trial & Usage Ledger System that underpins trial management, usage accounting, and entitlement enforcement across the application. It explains how trials are granted and tracked, how usage is recorded and reconciled, and how billing integrations (PayMongo and PayPal) update entitlements and ledger state. The system spans client-side logic, serverless functions, and database migrations to provide a consistent, auditable record of user entitlements and usage. + +## Project Structure +The project is a modern web app with: +- Client-side React UI and state management +- Serverless functions for billing and entitlement operations +- Supabase database schema and migrations +- Billing integrations via PayMongo and PayPal webhooks + +```mermaid +graph TB +subgraph "Client" +A["App Entry
src/main.jsx"] +B["App Shell
src/App.jsx"] +C["Global Store
src/store.jsx"] +D["Auth Module
src/auth.jsx"] +E["Billing Utilities
src/lib/billing.js"] +F["Entitlement Logic
src/lib/entitlement.js"] +G["Supabase Client
src/lib/supabase.js"] +H["Account Page
src/components/AccountPage.jsx"] +I["Settings Page
src/components/Settings.jsx"] +end +subgraph "Serverless Functions" +J["Create Checkout
supabase/functions/create-checkout/index.ts"] +K["PayMongo Webhook
supabase/functions/paymongo-webhook/index.ts"] +L["PayPal Webhook
supabase/functions/paypal-webhook/index.ts"] +M["Shared Entitlement
supabase/functions/_shared/entitlement.ts"] +end +subgraph "Database" +N["Schema v1
supabase/migrations/001_schema.sql"] +O["PayPal Fulfillment
supabase/migrations/002_paypal_fulfillment.sql"] +end +A --> B --> C +B --> D +B --> H +B --> I +C --> E +C --> F +C --> G +E --> J +J --> K +J --> L +K --> M +L --> M +M --> N +M --> O +``` + +**Diagram sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [README.md](file://README.md) +- [package.json](file://package.json) + +## Core Components +- App entry and shell: Initializes the application, mounts the root component, and wires up global providers and routing. +- Global store: Centralizes state for entitlements, trial status, and usage counters; exposes actions to update and persist state. +- Auth module: Manages authentication lifecycle and integrates with Supabase auth to scope entitlements per user. +- Billing utilities: Provides helpers to create checkouts and handle billing flows from the client. +- Entitlement logic: Encapsulates rules for trial eligibility, usage limits, and feature gating based on current entitlements. +- Supabase client: Configures the database client used by both client and serverless functions for reading/writing ledger data. +- Account and Settings pages: User-facing surfaces to view trial status, usage, and manage subscription settings. + +Key responsibilities: +- Maintain a single source of truth for trial and usage state +- Enforce feature access based on entitlements +- Record usage events and reconcile them with billing outcomes +- Provide UI for users to inspect and control their trial and subscription + +**Section sources** +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) + +## Architecture Overview +The Trial & Usage Ledger System follows a client-server architecture with event-driven updates from payment providers: +- The client initializes auth and loads entitlements and usage from the database. +- Users initiate checkout flows through serverless functions. +- Payment providers send webhooks to update entitlements and ledger entries. +- Shared entitlement logic ensures consistency between client and server. + +```mermaid +sequenceDiagram +participant U as "User" +participant FE as "Frontend (App)" +participant SC as "Store (State)" +participant BE as "Create Checkout Function" +participant PM as "Payment Provider" +participant WH as "Webhook Handler" +participant DB as "Database" +U->>FE : "Start checkout" +FE->>SC : "Initiate billing flow" +SC->>BE : "Create checkout session" +BE-->>PM : "Redirect to provider" +PM-->>U : "Payment completed" +PM-->>WH : "Send webhook" +WH->>DB : "Update entitlements and ledger" +DB-->>SC : "Sync updated state" +SC-->>FE : "Refresh UI with new entitlements" +``` + +**Diagram sources** +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Detailed Component Analysis + +### Client-Side State and UI +- App shell sets up providers and routes, ensuring entitlement-aware components render correctly. +- Global store holds trial metadata, usage counters, and entitlement flags; it exposes methods to increment usage and refresh entitlements. +- Account and Settings pages read from the store to display trial status, remaining usage, and allow users to manage subscriptions. + +```mermaid +classDiagram +class AppShell { ++mountProviders() ++renderRoutes() +} +class Store { ++state ++getEntitlements() ++incrementUsage(feature) ++refreshEntitlements() +} +class AccountPage { ++renderTrialStatus() ++renderUsageSummary() +} +class SettingsPage { ++renderSubscriptionOptions() ++handleCheckoutClick() +} +AppShell --> Store : "reads/writes" +AccountPage --> Store : "reads" +SettingsPage --> Store : "reads/writes" +``` + +**Diagram sources** +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) + +**Section sources** +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) + +### Billing Utilities and Checkout Flow +- Billing utilities orchestrate checkout creation and redirect to payment providers. +- Create checkout function prepares sessions and returns URLs for the client to navigate. + +```mermaid +sequenceDiagram +participant UI as "Settings Page" +participant Store as "Store" +participant Billing as "Billing Utilities" +participant Checkout as "Create Checkout Function" +participant Provider as "Payment Provider" +UI->>Store : "Request checkout" +Store->>Billing : "initiateCheckout(params)" +Billing->>Checkout : "POST /create-checkout" +Checkout-->>Billing : "{url}" +Billing-->>UI : "Redirect to provider URL" +``` + +**Diagram sources** +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +**Section sources** +- [src/lib/billing.js](file://src/lib/billing.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) + +### Entitlement Enforcement +- Client-side entitlement logic checks features against current entitlements derived from trial and subscription state. +- Server-side shared entitlement logic validates and computes entitlements consistently for webhooks and backend operations. + +```mermaid +flowchart TD +Start(["Feature Access Request"]) --> LoadState["Load Current Entitlements"] +LoadState --> CheckTrial{"Within Trial Period?"} +CheckTrial --> |Yes| AllowTrial["Allow Based on Trial Rules"] +CheckTrial --> |No| CheckSub{"Active Subscription?"} +CheckSub --> |Yes| AllowSub["Allow Based on Plan Limits"] +CheckSub --> |No| Deny["Deny Access"] +AllowTrial --> End(["Decision: Allowed"]) +AllowSub --> End +Deny --> End +``` + +**Diagram sources** +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +### Database Schema and Migrations +- Initial schema defines core tables for users, entitlements, and ledger entries. +- PayPal fulfillment migration adds structures to track PayPal-specific fulfillment records and reconciliation. + +```mermaid +erDiagram +USERS { +uuid id PK +string email UK +timestamp created_at +timestamp updated_at +} +ENTITLEMENTS { +uuid id PK +uuid user_id FK +enum type +boolean active +timestamp expires_at +timestamp created_at +timestamp updated_at +} +LEDGER_ENTRIES { +uuid id PK +uuid user_id FK +enum action +int quantity +text reference +timestamp occurred_at +} +PAYPAL_FULFILLMENT { +uuid id PK +uuid user_id FK +string order_id +string capture_id +enum status +timestamp fulfilled_at +} +USERS ||--o{ ENTITLEMENTS : "has many" +USERS ||--o{ LEDGER_ENTRIES : "has many" +USERS ||--o{ PAYPAL_FULFILLMENT : "has many" +``` + +**Diagram sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +### Webhook Handlers and Reconciliation +- PayMongo webhook handler processes payment confirmations and updates entitlements and ledger entries accordingly. +- PayPal webhook handler performs similar reconciliation for PayPal orders and captures. + +```mermaid +sequenceDiagram +participant PM as "PayMongo/PayPal" +participant WH as "Webhook Handler" +participant SE as "Shared Entitlement" +participant DB as "Database" +PM-->>WH : "Event payload" +WH->>SE : "Compute entitlement changes" +SE-->>WH : "Changes to apply" +WH->>DB : "Upsert entitlements and ledger" +DB-->>WH : "Confirmation" +WH-->>PM : "200 OK" +``` + +**Diagram sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Dependency Analysis +The Trial & Usage Ledger System has clear separation of concerns: +- Frontend depends on store, billing utilities, and entitlement logic to enforce access and present state. +- Serverless functions depend on shared entitlement logic and database schema to maintain consistency. +- Webhooks depend on provider payloads and shared entitlement computation to update state reliably. + +```mermaid +graph LR +FE["Frontend Modules"] --> Store["Store"] +FE --> Billing["Billing Utilities"] +FE --> Entitlement["Entitlement Logic"] +FE --> Supabase["Supabase Client"] +Billing --> Checkout["Create Checkout Function"] +Checkout --> Providers["Payment Providers"] +Providers --> Webhooks["Webhook Handlers"] +Webhooks --> SharedEnt["Shared Entitlement"] +SharedEnt --> DB["Database Schema"] +``` + +**Diagram sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [src/store.jsx](file://src/store.jsx) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Minimize redundant entitlement checks by caching results in the store and invalidating only when necessary. +- Batch usage increments where possible to reduce database writes during high-frequency interactions. +- Ensure webhook handlers are idempotent to avoid duplicate ledger entries on retries. +- Use efficient queries and indexes on frequently accessed fields such as user_id and timestamps. + +## Troubleshooting Guide +Common issues and resolutions: +- Entitlement mismatch between client and server: Verify shared entitlement logic and ensure both client and server use the same rules. +- Webhook not updating state: Confirm provider signatures, payload parsing, and idempotency keys; check database constraints and transaction boundaries. +- Checkout failures: Validate environment configuration for payment providers and ensure correct return URLs and secret keys. +- Usage not reflected in UI: Ensure store refresh triggers after successful webhook processing and that UI components subscribe to store updates. + +**Section sources** +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [src/store.jsx](file://src/store.jsx) + +## Conclusion +The Trial & Usage Ledger System provides a robust foundation for managing trials, tracking usage, and enforcing entitlements across the application. By centralizing entitlement logic, maintaining an auditable ledger, and integrating securely with payment providers, the system ensures consistent behavior and reliable state synchronization between client and server. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Billing & Subscriptions/Webhook Processing & Event Handling.md b/.qoder/repowiki/en/content/Billing & Subscriptions/Webhook Processing & Event Handling.md new file mode 100644 index 0000000..07c6a75 --- /dev/null +++ b/.qoder/repowiki/en/content/Billing & Subscriptions/Webhook Processing & Event Handling.md @@ -0,0 +1,379 @@ +# Webhook Processing & Event Handling + + +**Referenced Files in This Document** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains how ApplyGuard PH processes webhooks from PayMongo and PayPal, including endpoint implementations, request validation, signature verification, event handling, idempotency, retry behavior, error logging, monitoring, debugging techniques, security best practices, and payload transformation patterns. The goal is to provide a clear, actionable guide for developers and operators who maintain or extend webhook processing. + +## Project Structure +Webhook endpoints are implemented as Supabase Edge Functions under supabase/functions. Shared utilities for HTTP handling and PayPal runtime logic live under supabase/functions/_shared. Database schema changes related to PayPal fulfillment are defined in migrations. + +```mermaid +graph TB +subgraph "Supabase Edge Functions" +PMW["paymongo-webhook/index.ts"] +PPW["paypal-webhook/index.ts"] +SH_HTTP["_shared/http.ts"] +SH_PP_RUNTIME["_shared/paypal-runtime.ts"] +SH_PP["_shared/paypal.ts"] +end +subgraph "Database" +MIG_002["migrations/002_paypal_fulfillment.sql"] +end +PMW --> SH_HTTP +PPW --> SH_HTTP +PPW --> SH_PP_RUNTIME +PPW --> SH_PP +PPW --> MIG_002 +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Core Components +- PayMongo webhook handler: Receives events from PayMongo, validates the request, verifies signatures, transforms payloads into internal events, applies idempotency checks, persists state changes, and returns appropriate responses. +- PayPal webhook handler: Receives events from PayPal, validates headers and signatures using shared PayPal runtime utilities, maps PayPal events to internal actions, enforces idempotency, updates database records, and responds with success/failure semantics. +- Shared HTTP utilities: Provide common helpers for reading request bodies, parsing JSON, setting response headers, and returning standardized HTTP responses. +- Shared PayPal utilities: Implement PayPal-specific signature verification, event parsing, and helper functions used by the PayPal webhook handler. +- PayPal fulfillment migration: Defines database tables and constraints required for tracking PayPal order lifecycle and fulfillment state. + +Key responsibilities across components: +- Request validation (headers, content type, body shape) +- Signature verification (PayMongo and PayPal) +- Event routing based on event types +- Idempotency enforcement via unique identifiers +- Error logging and metrics-friendly outputs +- Safe retries and backoff strategies at the platform level + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Architecture Overview +The webhook architecture follows a simple, robust pattern: +- External provider sends an HTTP POST to the corresponding Edge Function. +- The function validates the request and verifies the signature. +- The payload is transformed into an internal event model. +- Idempotency is enforced using provider-supplied IDs. +- Business logic updates application state (e.g., subscription status). +- A consistent HTTP response is returned to signal success or failure. + +```mermaid +sequenceDiagram +participant Provider as "Payment Provider" +participant Edge as "Edge Function" +participant Util as "Shared Utilities" +participant DB as "Database" +Provider->>Edge : "POST /webhook/{provider}" +Edge->>Util : "Validate headers and parse body" +Edge->>Util : "Verify signature" +Util-->>Edge : "Signature valid/invalid" +Edge->>Edge : "Map provider event to internal event" +Edge->>DB : "Check idempotency key" +DB-->>Edge : "Already processed or new" +alt "New event" +Edge->>DB : "Apply business logic and persist state" +DB-->>Edge : "Success" +else "Duplicate event" +Edge-->>Provider : "200 OK (idempotent)" +end +Edge-->>Provider : "200 OK or 4xx/5xx" +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### PayMongo Webhook Handler +Responsibilities: +- Accepts PayMongo webhook requests. +- Validates content-type and parses JSON body. +- Verifies PayMongo signature using configured secret. +- Routes events by type (e.g., payment succeeded, failed, refunded). +- Enforces idempotency using PayMongo event ID. +- Persists outcome and returns appropriate HTTP status. + +Security and validation: +- Requires correct content-type header. +- Uses HMAC-based signature verification against the raw request body. +- Rejects malformed or unsigned requests early. + +Event handling: +- Maps PayMongo event types to internal actions. +- Updates subscription or entitlement state accordingly. + +Idempotency: +- Uses provider event ID as idempotency key. +- Skips reprocessing if already recorded. + +Error handling: +- Logs errors with context (event ID, type, partial payload). +- Returns non-200 status codes for failures to trigger provider retries. + +```mermaid +flowchart TD +Start(["Receive PayMongo Webhook"]) --> ValidateHeaders["Validate Content-Type and Headers"] +ValidateHeaders --> ParseBody["Parse JSON Body"] +ParseBody --> VerifySig["Verify PayMongo Signature"] +VerifySig --> SigValid{"Signature Valid?"} +SigValid --> |No| ReturnUnauthorized["Return 401 Unauthorized"] +SigValid --> |Yes| MapEvent["Map to Internal Event"] +MapEvent --> CheckIdem["Check Idempotency Key"] +CheckIdem --> AlreadyProc{"Already Processed?"} +AlreadyProc --> |Yes| ReturnOK["Return 200 OK"] +AlreadyProc --> |No| ApplyLogic["Apply Business Logic"] +ApplyLogic --> Persist["Persist State Changes"] +Persist --> ReturnOK +ReturnUnauthorized --> End(["Exit"]) +ReturnOK --> End +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +### PayPal Webhook Handler +Responsibilities: +- Accepts PayPal webhook requests. +- Validates headers and parses JSON body. +- Verifies PayPal signature using shared PayPal runtime utilities. +- Routes events by PayPal event type (e.g., ORDER.CAPTURED, BILLING.SUBSCRIPTION.ACTIVATED). +- Enforces idempotency using PayPal event ID. +- Applies fulfillment logic and updates database records. +- Returns proper HTTP status codes. + +Security and validation: +- Ensures required headers are present. +- Uses PayPal-provided signature verification flow. +- Rejects invalid or tampered payloads. + +Event handling: +- Transforms PayPal events into internal actions. +- Triggers order capture or subscription activation flows. + +Idempotency: +- Uses PayPal event ID to prevent duplicate processing. + +Error handling: +- Logs detailed context for debugging. +- Returns non-200 statuses to prompt provider retries. + +```mermaid +sequenceDiagram +participant PayPal as "PayPal" +participant PPW as "paypal-webhook/index.ts" +participant Runtime as "_shared/paypal-runtime.ts" +participant Utils as "_shared/paypal.ts" +participant DB as "Database" +PayPal->>PPW : "POST /webhook/paypal" +PPW->>Utils : "Validate headers and parse body" +PPW->>Runtime : "Verify signature" +Runtime-->>PPW : "Verification result" +PPW->>PPW : "Map PayPal event to internal action" +PPW->>DB : "Check idempotency key" +DB-->>PPW : "Result" +alt "New event" +PPW->>DB : "Update fulfillment state" +DB-->>PPW : "Success" +else "Duplicate event" +PPW-->>PayPal : "200 OK (idempotent)" +end +PPW-->>PayPal : "200 OK or 4xx/5xx" +``` + +**Diagram sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +**Section sources** +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +### Shared HTTP Utilities +Purpose: +- Standardize request parsing and response formatting. +- Provide helpers for reading raw body, parsing JSON, and setting headers. +- Centralize error response patterns for consistency. + +Usage: +- Both PayMongo and PayPal handlers use these utilities to ensure uniform validation and response behavior. + +**Section sources** +- [shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Shared PayPal Utilities +Purpose: +- Encapsulate PayPal-specific logic such as signature verification and event parsing helpers. +- Provide reusable functions for PayPal webhook processing. + +Usage: +- PayPal webhook handler delegates signature verification and event mapping to these utilities. + +**Section sources** +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +### PayPal Fulfillment Migration +Purpose: +- Define database schema for PayPal order lifecycle and fulfillment state. +- Ensure referential integrity and constraints for reliable processing. + +Usage: +- PayPal webhook handler writes to and reads from these tables to track fulfillment progress. + +**Section sources** +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Dependency Analysis +The following diagram illustrates dependencies between webhook handlers and shared modules. + +```mermaid +graph LR +PMW["paymongo-webhook/index.ts"] --> SH_HTTP["_shared/http.ts"] +PPW["paypal-webhook/index.ts"] --> SH_HTTP +PPW --> SH_PP_RUNTIME["_shared/paypal-runtime.ts"] +PPW --> SH_PP["_shared/paypal.ts"] +PPW --> MIG_002["migrations/002_paypal_fulfillment.sql"] +``` + +**Diagram sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) + +## Performance Considerations +- Keep webhook handlers fast and idempotent; avoid heavy computations inside the critical path. +- Use minimal I/O; batch operations where possible and prefer single transactions for state updates. +- Leverage provider retry semantics by responding promptly with correct status codes. +- Monitor latency and error rates; set alerts for anomalies. +- Avoid unnecessary logging of sensitive data; log only what is needed for debugging. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and steps: +- Signature verification failures: + - Confirm secrets are correctly configured and not rotated without updating providers. + - Ensure raw body is used for signature computation. + - Validate that content-type matches expectations. +- Duplicate processing: + - Verify idempotency keys are derived from provider event IDs. + - Check database constraints to prevent duplicates. +- Missing fields or malformed payloads: + - Add defensive parsing and return 400-level errors with descriptive messages. + - Log enough context to reproduce the issue without exposing secrets. +- Provider retries: + - Non-200 responses will cause retries; investigate root causes and fix quickly. + - For transient errors, consider short delays before finalizing responses. + +Debugging techniques: +- Enable structured logging with correlation IDs (e.g., provider event ID). +- Capture request metadata (headers, timestamps) and sanitized payloads. +- Use database audit logs to trace state transitions. +- Reproduce locally with provider webhook simulators when available. + +**Section sources** +- [paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [shared/http.ts](file://supabase/functions/_shared/http.ts) +- [shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) + +## Conclusion +ApplyGuard PH implements secure, idempotent webhook processing for PayMongo and PayPal using Supabase Edge Functions and shared utilities. By validating requests, verifying signatures, mapping events to internal models, enforcing idempotency, and returning appropriate HTTP statuses, the system ensures reliability and safety. Operators should monitor performance, log thoughtfully, and follow security best practices to maintain robust webhook pipelines. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Security Best Practices +- Always verify signatures using the raw request body and provider-provided secrets. +- Restrict access to webhook endpoints at the platform level (e.g., IP allowlists where supported). +- Never log secrets or sensitive payload fields. +- Use HTTPS-only endpoints and enforce TLS. +- Rotate secrets securely and update providers promptly. + +[No sources needed since this section provides general guidance] + +### Payload Transformation Patterns +- Normalize provider payloads into a unified internal event schema. +- Extract core identifiers (e.g., customer ID, order ID, event ID) consistently. +- Map provider-specific fields to internal enums and states. +- Preserve original payload for auditability while working with normalized structures. + +[No sources needed since this section provides general guidance] + +### Idempotency Requirements +- Use provider event IDs as idempotency keys. +- Store processed event IDs in the database with unique constraints. +- Skip processing for duplicates and return success to acknowledge receipt. + +[No sources needed since this section provides general guidance] + +### Retry Mechanisms +- Respond with non-200 status codes for failures to trigger provider retries. +- Implement exponential backoff at the provider side; avoid long-running operations in handlers. +- Track retry counts and escalate persistent failures. + +[No sources needed since this section provides general guidance] + +### Monitoring and Observability +- Instrument metrics for webhook volume, latency, and error rates. +- Set up alerts for spikes in failures or latency. +- Correlate logs with provider event IDs for end-to-end tracing. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Business Logic Layer.md b/.qoder/repowiki/en/content/Business Logic Layer/Business Logic Layer.md new file mode 100644 index 0000000..a6f9590 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Business Logic Layer.md @@ -0,0 +1,482 @@ +# Business Logic Layer + + +**Referenced Files in This Document** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the business logic layer of ApplyGuard PH, focusing on the analysis engine for resume scanning, scoring algorithms for job applications, follow-up automation, and statistics calculation. It also documents the red flag detection system, tone analysis algorithms, and next action suggestion engine. The goal is to provide a clear understanding of the decision trees, mathematical formulas, and configuration parameters that drive these features, enabling customization for different use cases. + +## Project Structure +The business logic resides primarily under src/lib with supporting UI components and state management: +- Analysis pipeline: analyze.js orchestrates parsing, feature extraction, and aggregation. +- Scoring: scoring.js computes composite scores from weighted criteria. +- Red flags: redflags.js identifies risk signals and policy violations. +- Tone: tone.js evaluates communication tone and sentiment. +- Next actions: nextaction.js suggests actionable steps based on analysis outcomes. +- Follow-ups: followups.js automates reminders and scheduling rules. +- Statistics: stats.js aggregates metrics across applications and campaigns. +- AI integration: ai.js and prompt.js manage prompts and external model calls. +- Data persistence: supabase.js provides storage and sync utilities. +- State and UI: store.jsx manages application state; ScanForm.jsx, ResultView.jsx, Tracker.jsx implement user workflows. + +```mermaid +graph TB +subgraph "UI" +SF["ScanForm.jsx"] +RV["ResultView.jsx"] +TR["Tracker.jsx"] +end +subgraph "State" +ST["store.jsx"] +end +subgraph "Business Logic" +AN["analyze.js"] +SC["scoring.js"] +RF["redflags.js"] +TO["tone.js"] +NA["nextaction.js"] +FU["followups.js"] +STS["stats.js"] +end +subgraph "AI & Prompts" +AI["ai.js"] +PR["prompt.js"] +end +subgraph "Data" +SB["supabase.js"] +end +SF --> ST +RV --> ST +TR --> ST +ST --> AN +AN --> SC +AN --> RF +AN --> TO +AN --> NA +AN --> FU +AN --> STS +AN --> AI +AI --> PR +AN --> SB +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Core Components +- Analysis Engine (analyze.js): Orchestrates input normalization, feature extraction, and pipeline execution. It coordinates scoring, red flag detection, tone analysis, next action generation, and follow-up scheduling. +- Scoring Engine (scoring.js): Computes weighted scores across multiple dimensions such as experience relevance, skill match, education alignment, and formatting quality. Supports configurable weights and thresholds. +- Red Flag Detection (redflags.js): Identifies high-risk indicators like gaps, inconsistencies, or policy violations using rule-based checks and heuristics. +- Tone Analyzer (tone.js): Evaluates tone and sentiment of cover letters or messages, providing qualitative insights and numeric indicators. +- Next Action Suggestion (nextaction.js): Generates prioritized recommendations based on analysis results, red flags, and scoring outcomes. +- Follow-up Automation (followups.js): Manages reminder schedules, status transitions, and automated nudges based on application lifecycle events. +- Statistics Aggregation (stats.js): Calculates KPIs such as conversion rates, average scores, time-to-response, and campaign performance. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) + +## Architecture Overview +The business logic follows a modular pipeline architecture: +- Input normalization and validation occur first. +- Feature extraction feeds into parallel analyzers (scoring, red flags, tone). +- Results are aggregated by the analysis engine to produce a unified profile. +- Next actions and follow-ups are derived from the aggregated profile. +- Statistics are updated incrementally as new data arrives. +- AI modules can augment analysis via prompts and external models. + +```mermaid +sequenceDiagram +participant UI as "ScanForm.jsx" +participant Store as "store.jsx" +participant Engine as "analyze.js" +participant Score as "scoring.js" +participant Flags as "redflags.js" +participant Tone as "tone.js" +participant Actions as "nextaction.js" +participant Follow as "followups.js" +participant Stats as "stats.js" +participant AI as "ai.js" +participant DB as "supabase.js" +UI->>Store : Submit resume/application +Store->>Engine : Normalize and validate input +Engine->>Score : Compute weighted score +Engine->>Flags : Detect red flags +Engine->>Tone : Analyze tone/sentiment +Engine->>AI : Optional augmentation via prompts +Engine-->>Store : Aggregated analysis result +Store->>Actions : Generate next actions +Store->>Follow : Schedule follow-ups +Store->>Stats : Update statistics +Store->>DB : Persist results +DB-->>Store : Acknowledge +Store-->>UI : Display results and suggestions +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Analysis Engine (analyze.js) +Responsibilities: +- Input normalization and schema validation. +- Orchestration of scoring, red flag detection, tone analysis, and optional AI augmentation. +- Aggregation of results into a unified analysis object. +- Triggering downstream processes (next actions, follow-ups, statistics). + +Key behaviors: +- Validates required fields and formats inputs consistently. +- Calls scoring, red flags, and tone analyzers concurrently where possible. +- Integrates AI outputs when enabled, merging them with rule-based results. +- Emits structured results consumed by UI and persistence layers. + +```mermaid +flowchart TD +Start(["Start Analysis"]) --> Validate["Validate and normalize input"] +Validate --> Valid{"Valid?"} +Valid --> |No| Error["Return validation error"] +Valid --> |Yes| Parallel["Run parallel analyzers:
Scoring, Red Flags, Tone"] +Parallel --> AICheck{"AI augmentation enabled?"} +AICheck --> |Yes| CallAI["Call AI module with prompts"] +AICheck --> |No| Merge["Merge analyzer outputs"] +CallAI --> Merge +Merge --> Aggregate["Aggregate into unified profile"] +Aggregate --> Actions["Generate next actions"] +Aggregate --> FollowUps["Schedule follow-ups"] +Aggregate --> Stats["Update statistics"] +Stats --> Persist["Persist to storage"] +Persist --> End(["End"]) +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Scoring Engine (scoring.js) +Responsibilities: +- Compute composite scores from multiple weighted criteria. +- Support configurable weights, thresholds, and normalization strategies. + +Mathematical model: +- Composite score S = Σ(w_i * s_i), where w_i are normalized weights (Σw_i = 1) and s_i are normalized sub-scores per criterion. +- Normalization may use min-max scaling or percentile ranking depending on data distribution. +- Thresholds determine categories (e.g., low, medium, high) and trigger downstream actions. + +Decision tree: +- If S >= high_threshold → “Strong candidate” +- Else if S >= medium_threshold → “Moderate candidate” +- Else → “Needs improvement” + +Configuration parameters: +- Weights per criterion (experience, skills, education, formatting). +- Threshold boundaries for categories. +- Normalization method selection. +- Penalty/bonus multipliers for specific signals. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) + +### Red Flag Detection (redflags.js) +Responsibilities: +- Identify risk indicators through rule-based checks and heuristics. +- Categorize flags by severity and domain (employment history, education, content consistency). + +Rule examples: +- Employment gap > threshold → “Gap detected” +- Repeated job titles without progression → “Stagnation signal” +- Inconsistent dates or missing sections → “Inconsistency” + +Severity scoring: +- Each flag has a severity weight; aggregate severity influences overall risk level. +- Risk levels guide next actions and follow-up urgency. + +Decision flow: +- For each rule, evaluate conditions against normalized features. +- Accumulate flagged items with severity and context. +- Produce a summary risk score and detailed flag list. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) + +### Tone Analyzer (tone.js) +Responsibilities: +- Evaluate tone and sentiment of textual inputs (cover letters, messages). +- Provide qualitative labels (positive, neutral, negative) and numeric indicators. + +Algorithm outline: +- Tokenize text and extract sentiment-bearing phrases. +- Apply lexicon-based scoring or lightweight ML model to compute sentiment score. +- Map score to tone categories and highlight key phrases. + +Output: +- Numeric sentiment score within a defined range. +- Categorized tone label. +- Highlighted excerpts contributing to the assessment. + +**Section sources** +- [tone.js](file://src/lib/tone.js) + +### Next Action Suggestion (nextaction.js) +Responsibilities: +- Generate prioritized recommendations based on analysis results. +- Combine scoring outcomes, red flags, and tone insights to propose concrete steps. + +Recommendation logic: +- If low score and specific weak criteria → suggest targeted improvements. +- If red flags present → propose remediation steps and verification. +- If positive tone but low score → emphasize content structure and keyword alignment. + +Prioritization: +- Rank actions by impact and effort, considering urgency from red flags. +- Provide templates or links to resources where applicable. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) + +### Follow-up Automation (followups.js) +Responsibilities: +- Manage reminder schedules and status transitions. +- Automate nudges based on application lifecycle events. + +Rules: +- After submission → schedule initial check-in. +- If no response after X days → send follow-up message. +- On status change (e.g., interview scheduled) → update timeline and next steps. + +Scheduling: +- Use event-driven triggers and configurable intervals. +- Maintain audit trail of sent messages and responses. + +**Section sources** +- [followups.js](file://src/lib/followups.js) + +### Statistics Aggregation (stats.js) +Responsibilities: +- Calculate KPIs across applications and campaigns. +- Track conversion rates, average scores, time-to-response, and success metrics. + +Metrics: +- Conversion rate = successful outcomes / total applications. +- Average score per category and overall. +- Time-to-response distributions and median values. +- Campaign-level performance comparisons. + +Aggregation strategy: +- Incremental updates on new data. +- Rolling windows for trend analysis. +- Exportable summaries for reporting. + +**Section sources** +- [stats.js](file://src/lib/stats.js) + +### AI Integration (ai.js, prompt.js) +Responsibilities: +- Manage prompts and external model calls to augment analysis. +- Integrate AI outputs with rule-based results. + +Workflow: +- Construct prompts based on current analysis context. +- Call AI service and parse responses. +- Merge AI insights into the unified profile, preserving confidence scores. + +Configuration: +- Prompt templates and variables. +- Model selection and fallback behavior. +- Rate limiting and error handling. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +### Data Persistence (supabase.js) +Responsibilities: +- Provide storage and synchronization utilities. +- Persist analysis results, follow-up logs, and statistics. + +Operations: +- Upsert records for applications and analysis profiles. +- Sync local state with remote storage. +- Handle conflicts and retries. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) + +### UI and State Management (store.jsx, ScanForm.jsx, ResultView.jsx, Tracker.jsx) +Responsibilities: +- Manage application state and user interactions. +- Present analysis results, suggestions, and tracking information. + +Flow: +- ScanForm collects input and submits to store. +- Store invokes analysis engine and updates state. +- ResultView displays scores, flags, tone, and next actions. +- Tracker monitors follow-ups and status changes. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Dependency Analysis +The business logic modules have clear dependencies: +- analyze.js depends on scoring, redflags, tone, nextaction, followups, stats, ai, and supabase. +- UI components depend on store.jsx for state and side effects. +- AI modules depend on prompt templates and external services. + +```mermaid +graph LR +AN["analyze.js"] --> SC["scoring.js"] +AN --> RF["redflags.js"] +AN --> TO["tone.js"] +AN --> NA["nextaction.js"] +AN --> FU["followups.js"] +AN --> STS["stats.js"] +AN --> AI["ai.js"] +AN --> SB["supabase.js"] +AI --> PR["prompt.js"] +UI["store.jsx"] --> AN +UI --> RV["ResultView.jsx"] +UI --> SF["ScanForm.jsx"] +UI --> TR["Tracker.jsx"] +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) + +## Performance Considerations +- Parallel execution: Run independent analyzers concurrently to reduce latency. +- Incremental updates: Update statistics and persisted records only when necessary. +- Caching: Cache repeated AI prompts and results where appropriate. +- Batching: Batch database writes to minimize network overhead. +- Memory management: Avoid large intermediate objects; stream processing where feasible. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Validation errors: Ensure input schemas match expected formats; review normalize functions. +- Scoring anomalies: Check weight configurations and normalization methods; verify thresholds. +- Red flag false positives: Adjust rule thresholds and add exceptions for known patterns. +- Tone misclassification: Review lexicon or model inputs; refine prompt templates. +- AI failures: Implement fallbacks and retry logic; monitor rate limits and error codes. +- Persistence conflicts: Resolve upsert conflicts and ensure consistent IDs. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [tone.js](file://src/lib/tone.js) +- [ai.js](file://src/lib/ai.js) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +The business logic layer of ApplyGuard PH provides a robust, modular pipeline for resume analysis, scoring, red flag detection, tone evaluation, next action suggestions, follow-up automation, and statistics aggregation. With configurable parameters and clear decision flows, it supports customization for diverse use cases while maintaining performance and reliability. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices +- Configuration reference: Weights, thresholds, and normalization options for scoring. +- Rule catalog: Red flag definitions and severity mappings. +- Prompt library: Templates used by AI augmentation. +- API contracts: Interfaces between modules and external services. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Follow-up Management System.md b/.qoder/repowiki/en/content/Business Logic Layer/Follow-up Management System.md new file mode 100644 index 0000000..dced8b6 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Follow-up Management System.md @@ -0,0 +1,371 @@ +# Follow-up Management System + + +**Referenced Files in This Document** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the follow-up automation system in ApplyGuard PH. It focuses on how the application schedules intelligent follow-ups, manages email templates and reminders, and orchestrates automated notifications based on application status, industry norms, and user preferences. It also covers decision trees for different scenarios, escalation rules, user interaction patterns, and integrations with calendar systems, email services, and notification channels. Examples of workflows and customization options are provided to help users tailor follow-up strategies to their job search approach. + +## Project Structure +The follow-up system is implemented primarily in client-side JavaScript modules and React components: +- Scheduling logic and algorithms reside in a dedicated library module. +- UI components expose configuration and visualization of follow-ups. +- State management centralizes data access and persistence. +- Integrations leverage Supabase for storage and optional cloud functions. + +```mermaid +graph TB +subgraph "UI" +Tracker["Tracker.jsx"] +Settings["Settings.jsx"] +end +subgraph "Libraries" +Followups["followups.js"] +NextAction["nextaction.js"] +Stats["stats.js"] +AI["ai.js"] +Prompt["prompt.js"] +end +subgraph "Storage & Sync" +Store["store.jsx"] +Supabase["supabase.js"] +end +Tracker --> Followups +Settings --> Followups +Followups --> NextAction +Followups --> Stats +Followups --> AI +Followups --> Prompt +Followups --> Store +Store --> Supabase +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +## Core Components +- Intelligent scheduling engine: Computes optimal follow-up timing using application status, industry norms, and user preferences. It integrates scoring and next-action heuristics to determine when and how often to remind users. +- Email template system: Provides templating utilities and prompt-based generation to create personalized follow-up messages aligned with tone and context. +- Reminder triggers and notifications: Orchestrates periodic checks, evaluates due follow-ups, and dispatches reminders via available channels (in-app, email, calendar). +- Decision trees and escalation rules: Encodes scenario-specific logic for first contact, second touch, escalation, and closure paths. +- User interaction patterns: Exposes settings to customize cadence, preferred channels, and strategy presets. + +Key responsibilities by file: +- Scheduling and decision logic: [followups.js](file://src/lib/followups.js), [nextaction.js](file://src/lib/nextaction.js) +- Scoring and statistics: [stats.js](file://src/lib/stats.js) +- Template and prompt generation: [ai.js](file://src/lib/ai.js), [prompt.js](file://src/lib/prompt.js) +- UI configuration and display: [Tracker.jsx](file://src/components/Tracker.jsx), [Settings.jsx](file://src/components/Settings.jsx) +- Data persistence and sync: [store.jsx](file://src/store.jsx), [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Architecture Overview +The follow-up system follows a modular architecture: +- The UI layer reads/writes user preferences and displays scheduled follow-ups. +- The scheduling engine consumes application state, scoring, and next-action signals to compute due dates and actions. +- Templates and prompts generate content for emails and notifications. +- Storage and sync persist follow-up records and settings. + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx" +participant Settings as "Settings.jsx" +participant Engine as "followups.js" +participant Next as "nextaction.js" +participant Score as "stats.js" +participant AI as "ai.js" +participant Prompt as "prompt.js" +participant Store as "store.jsx" +participant DB as "supabase.js" +UI->>Engine : Request schedule updates +Settings->>Engine : Update preferences +Engine->>Next : Compute next action signals +Engine->>Score : Read scores and stats +Engine->>AI : Generate message content +AI->>Prompt : Resolve prompts +Engine->>Store : Persist follow-up tasks +Store->>DB : Sync to backend +Engine-->>UI : Return updated schedule +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Scheduling Engine (followups.js) +Responsibilities: +- Determine optimal follow-up intervals based on application status, industry norms, and user preferences. +- Integrate next-action signals and scoring metrics to adjust cadence. +- Manage reminder triggers and escalation thresholds. +- Coordinate with template generation for message content. + +Key behaviors: +- Status-driven cadence: Different statuses (e.g., applied, interview, offer) influence recommended intervals. +- Industry normalization: Adjusts baseline intervals according to sector characteristics. +- Preference overrides: Allows users to set minimum/maximum intervals and preferred channels. +- Escalation rules: Increases frequency or changes channel after non-response windows. + +```mermaid +flowchart TD +Start(["Start Schedule Cycle"]) --> LoadPrefs["Load User Preferences"] +LoadPrefs --> LoadApps["Load Applications and Statuses"] +LoadApps --> ComputeSignals["Compute Next Action Signals"] +ComputeSignals --> ScoreStats["Read Scores and Stats"] +ScoreStats --> DecideCadence["Decide Cadence
by Status + Norms + Preferences"] +DecideCadence --> CheckDue{"Follow-up Due?"} +CheckDue --> |No| End(["End Cycle"]) +CheckDue --> |Yes| GenerateContent["Generate Content via AI/Prompt"] +GenerateContent --> CreateTask["Create Reminder Task"] +CreateTask --> Persist["Persist via Store/Sync"] +Persist --> End +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Next Action Heuristics (nextaction.js) +Responsibilities: +- Provide signals that inform scheduling decisions (e.g., urgency, likelihood of response). +- Encode domain knowledge about typical hiring timelines and best practices. + +Integration points: +- Consumed by the scheduling engine to refine cadence and escalation thresholds. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) + +### Scoring and Statistics (stats.js) +Responsibilities: +- Maintain application-level metrics used to personalize follow-up timing. +- Track historical response rates and conversion signals. + +Integration points: +- Used by the scheduling engine to adapt intervals based on observed performance. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) + +### Template and Prompt Generation (ai.js, prompt.js) +Responsibilities: +- Generate personalized follow-up messages using AI capabilities. +- Resolve prompts to ensure consistent tone and structure. + +Integration points: +- Called by the scheduling engine when creating new follow-up tasks. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [followups.js](file://src/lib/followups.js) + +### UI Configuration and Display (Tracker.jsx, Settings.jsx) +Responsibilities: +- Display current follow-up schedule and allow manual adjustments. +- Capture user preferences such as cadence limits, preferred channels, and strategy presets. + +Integration points: +- Reads from and writes to the store; triggers re-scheduling when preferences change. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [followups.js](file://src/lib/followups.js) + +### Data Persistence and Sync (store.jsx, supabase.js) +Responsibilities: +- Centralize state for applications, follow-ups, and preferences. +- Sync local state with Supabase for cross-device consistency. + +Integration points: +- Used by the scheduling engine to persist generated tasks and read latest preferences. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [followups.js](file://src/lib/followups.js) + +## Dependency Analysis +The following diagram shows key dependencies among modules involved in follow-up automation: + +```mermaid +graph LR +Followups["followups.js"] --> NextAction["nextaction.js"] +Followups --> Stats["stats.js"] +Followups --> AI["ai.js"] +Followups --> Prompt["prompt.js"] +Followups --> Store["store.jsx"] +Store --> Supabase["supabase.js"] +Tracker["Tracker.jsx"] --> Followups +Settings["Settings.jsx"] --> Followups +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Performance Considerations +- Batch processing: Group follow-up computations to minimize repeated reads/writes. +- Lazy evaluation: Defer heavy operations like AI-generated content until needed. +- Caching: Cache industry norms and preference lookups to reduce recomputation. +- Throttling: Limit scheduling cycles to avoid excessive background work. +- Incremental updates: Only recompute affected applications when preferences change. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing preferences: Ensure user preferences are initialized before scheduling runs. +- Stale data: Verify store synchronization with Supabase to prevent outdated follow-ups. +- Template errors: Validate prompt resolution and AI integration inputs. +- Duplicate tasks: Implement idempotency keys when persisting follow-up tasks. +- Channel failures: Log and fallback gracefully when email/calendar channels are unavailable. + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +## Conclusion +The follow-up automation system combines intelligent scheduling, templated messaging, and robust persistence to keep job seekers proactive and organized. By leveraging application status, industry norms, and user preferences, it delivers timely reminders and escalations while maintaining flexibility for diverse job search strategies. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Decision Trees for Follow-up Scenarios +- First contact: Initial interval based on industry norms and user preference; escalate if no response within threshold. +- Second touch: Shorter interval with adjusted tone; consider alternative channel if primary fails. +- Final attempt: Maximum frequency cap; mark for closure if still no response. +- Positive response: Pause follow-ups and update status accordingly. + +```mermaid +flowchart TD +A["Application Status"] --> B{"Status = Applied?"} +B --> |Yes| C["Set Baseline Interval by Industry Norms"] +B --> |No| D{"Status = Interview/Offer?"} +D --> |Yes| E["Reduce Frequency / Focus on Preparation"] +D --> |No| F["Other Status -> Minimal Follow-up"] +C --> G{"User Preference Overrides?"} +G --> |Yes| H["Apply Min/Max Intervals and Channels"] +G --> |No| I["Use Defaults"] +H --> J["Check Response Window"] +I --> J +J --> K{"Response Received?"} +K --> |Yes| L["Pause Follow-ups and Update Status"] +K --> |No| M["Escalate: Increase Frequency or Change Channel"] +M --> N{"Max Attempts Reached?"} +N --> |Yes| O["Mark for Closure"] +N --> |No| P["Schedule Next Attempt"] +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +### Integration Points +- Calendar systems: Create events for upcoming follow-ups using platform APIs. +- Email services: Send templated messages through configured providers. +- Notification channels: In-app alerts, push notifications, or SMS depending on user preferences. + +[No sources needed since this section provides general guidance] + +### Customization Options for Job Search Strategies +- Aggressive strategy: Short intervals, frequent touches, multiple channels. +- Balanced strategy: Moderate intervals, primary channel focus, standard escalation. +- Conservative strategy: Longer intervals, minimal touches, low noise. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Next Action Suggestion Engine.md b/.qoder/repowiki/en/content/Business Logic Layer/Next Action Suggestion Engine.md new file mode 100644 index 0000000..ddfade2 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Next Action Suggestion Engine.md @@ -0,0 +1,383 @@ +# Next Action Suggestion Engine + + +**Referenced Files in This Document** +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the Next Action Suggestion Engine in ApplyGuard PH. It focuses on how the system analyzes application status, market conditions, and user behavior to recommend optimal next steps such as interview preparation, follow-up actions, application improvements, and alternative strategies. The engine combines rule-based logic with optional AI assistance, prioritizes actions using a scoring system, and personalizes recommendations based on user preferences and historical patterns. + +## Project Structure +The suggestion engine is implemented primarily in client-side libraries under src/lib and integrates with UI components and global state: + +- Recommendation algorithms and decision logic: nextaction.js, followups.js, scoring.js, analyze.js, redflags.js, stats.js +- Prompting and optional AI-assisted suggestions: prompt.js, ai.js +- State integration and UI rendering: store.jsx, Tracker.jsx + +```mermaid +graph TB +subgraph "Libraries" +NA["nextaction.js"] +FU["followups.js"] +SC["scoring.js"] +AN["analyze.js"] +RF["redflags.js"] +ST["stats.js"] +PR["prompt.js"] +AI["ai.js"] +end +subgraph "State and UI" +STX["store.jsx"] +TRK["Tracker.jsx"] +end +TRK --> STX +STX --> NA +NA --> FU +NA --> SC +NA --> AN +NA --> RF +NA --> ST +NA --> PR +PR --> AI +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Core Components +- Decision matrix and priority scoring: The engine evaluates multiple signals (application stage, recency, success rates, red flags, and performance metrics) to compute a composite score for candidate actions. +- Contextual awareness: Uses recent activity, conversion funnels, and failure points to tailor suggestions. +- Personalization: Adapts to user preferences, past responses, and chosen focus areas. +- Optional AI assistance: Augments rule-based outputs with contextual prompts and summaries when enabled. + +Key responsibilities by module: +- nextaction.js: Orchestrates recommendation generation, merges signals, applies rules, and returns ranked suggestions. +- followups.js: Determines timely follow-ups based on application lifecycle and response windows. +- scoring.js: Computes action scores from weighted features and thresholds. +- analyze.js: Extracts insights from application data and funnel metrics. +- redflags.js: Identifies risk indicators that influence urgency and strategy shifts. +- stats.js: Aggregates performance statistics used for personalization and calibration. +- prompt.js and ai.js: Build prompts and optionally call AI services to refine or expand suggestions. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +## Architecture Overview +The engine follows a layered architecture: +- Data layer: Application records, user history, and aggregated stats. +- Signal extraction: Analyze and red-flag modules derive actionable signals. +- Scoring and ranking: Weighted scoring produces prioritized candidates. +- Policy and context: Follow-up timing and contextual rules adjust priorities. +- Output: Ranked list of suggested next actions with explanations and optional AI-enhanced details. + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx" +participant Store as "store.jsx" +participant Engine as "nextaction.js" +participant Signals as "analyze.js + redflags.js" +participant Stats as "stats.js" +participant Followups as "followups.js" +participant Score as "scoring.js" +participant AI as "prompt.js + ai.js" +UI->>Store : Request suggestions +Store->>Engine : Provide current state and history +Engine->>Signals : Extract signals (status, risks) +Engine->>Stats : Load performance metrics +Engine->>Followups : Compute due follow-ups +Engine->>Score : Score candidate actions +alt AI enabled +Engine->>AI : Build prompt and request refinement +AI-->>Engine : Enhanced suggestions +end +Engine-->>Store : Ranked suggestions +Store-->>UI : Render suggestions +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +## Detailed Component Analysis + +### Decision Matrix and Priority Scoring +The engine builds a decision matrix from: +- Application stage and recency +- Response windows and overdue follow-ups +- Conversion rates and drop-off points +- Red flag severity +- User preference weights and focus areas + +Scoring combines these factors into a composite score per candidate action. Higher scores indicate higher priority. Thresholds determine whether an action is recommended, deferred, or deprioritized. + +```mermaid +flowchart TD +Start(["Start"]) --> Gather["Gather signals
stage, recency, follow-ups, red flags, stats"] +Gather --> Candidates["Generate candidate actions"] +Candidates --> Score["Compute weighted scores"] +Score --> Threshold{"Above threshold?"} +Threshold --> |No| Deprioritize["Deprioritize or skip"] +Threshold --> |Yes| Rank["Rank by score"] +Rank --> Personalize["Apply personalization filters"] +Personalize --> Output(["Return ranked suggestions"]) +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [scoring.js](file://src/lib/scoring.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [scoring.js](file://src/lib/scoring.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) + +### Contextual Awareness and Personalization +Contextual inputs include: +- Recent activity cadence and time since last update +- Funnel bottlenecks (e.g., low interview-to-offer conversion) +- Market signals inferred from application outcomes and feedback +- User-defined preferences (e.g., prioritize networking vs. application volume) + +Personalization adjusts weights and filters to align with user goals and past behavior. + +```mermaid +classDiagram +class Context { ++recentActivity ++funnelMetrics ++marketSignals ++userPreferences +} +class Personalizer { ++adjustWeights(context) ++filterCandidates(context) +} +Context <.. Personalizer : "provides inputs" +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) + +### Rule-Based Recommendations +Rule categories: +- Interview preparation: Triggered when upcoming interviews are detected or when historical interview performance indicates gaps. +- Follow-up actions: Based on elapsed time since submission or last contact; escalates if overdue. +- Application improvements: Activated when red flags or low conversion rates suggest resume/portfolio tweaks. +- Alternative strategies: Engaged when persistent failures occur across channels, prompting pivot tactics. + +These rules are evaluated before scoring to shape candidate sets and initial weights. + +```mermaid +flowchart TD +RStart(["Rules Entry"]) --> CheckInterview{"Upcoming interview?"} +CheckInterview --> |Yes| Prep["Add interview prep action"] +CheckInterview --> |No| CheckFollowup{"Follow-up due?"} +CheckFollowup --> |Yes| Follow["Add follow-up action"] +CheckFollowup --> |No| CheckRedFlags{"Red flags present?"} +CheckRedFlags --> |Yes| Improve["Add application improvement action"] +CheckRedFlags --> |No| CheckPivot{"Persistent low conversion?"} +CheckPivot --> |Yes| Pivot["Add alternative strategy action"] +CheckPivot --> |No| EndR(["No rule-triggered action"]) +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [nextaction.js](file://src/lib/nextaction.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [nextaction.js](file://src/lib/nextaction.js) + +### AI-Assisted Suggestions (Optional) +When enabled, the engine constructs a focused prompt summarizing current context and candidate actions, then requests AI refinement. Results are merged back into the ranked list with clear attribution. + +```mermaid +sequenceDiagram +participant Engine as "nextaction.js" +participant Prompt as "prompt.js" +participant AI as "ai.js" +Engine->>Prompt : Build context summary +Prompt->>AI : Send prompt +AI-->>Prompt : Return refined suggestions +Prompt-->>Engine : Merge results +``` + +**Diagram sources** +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [nextaction.js](file://src/lib/nextaction.js) + +**Section sources** +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [nextaction.js](file://src/lib/nextaction.js) + +### Example Scenarios and Customization +- Scenario A: Upcoming technical interview + - Triggers: Interview detection, low mock interview scores + - Actions: Targeted practice plan, common question review, portfolio polish +- Scenario B: No response after two weeks + - Triggers: Follow-up window exceeded + - Actions: Polite follow-up message, alternative channel outreach, role adjustment +- Scenario C: Low conversion across applications + - Triggers: Red flags, declining funnel metrics + - Actions: Resume rewrite, skill gap analysis, networking push, niche targeting +- Scenario D: High success rate in specific roles + - Triggers: Positive stats for certain job types + - Actions: Increase volume in high-yield segments, leverage referrals + +Customization options: +- Preference weights for effort vs. speed +- Focus areas (e.g., remote-only, salary targets) +- Communication style for follow-ups +- Frequency of suggestions and notification settings + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +The engine’s dependencies form a cohesive pipeline: + +```mermaid +graph LR +Store["store.jsx"] --> Next["nextaction.js"] +Next --> Followups["followups.js"] +Next --> Scoring["scoring.js"] +Next --> Analyze["analyze.js"] +Next --> Redflags["redflags.js"] +Next --> Stats["stats.js"] +Next --> Prompt["prompt.js"] +Prompt --> AI["ai.js"] +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +## Performance Considerations +- Keep signal computation lightweight; cache frequently accessed stats and funnel metrics. +- Defer AI calls to background tasks or user-initiated actions to avoid blocking UI. +- Use incremental updates for suggestions when only minor state changes occur. +- Limit the number of candidate actions to reduce scoring overhead. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing data: Ensure application records and timestamps are complete; validate required fields before scoring. +- Stale suggestions: Refresh stats and funnel metrics when state changes; invalidate cached computations. +- Overly aggressive follow-ups: Adjust follow-up windows and escalation thresholds based on user feedback. +- AI errors: Handle network failures gracefully; fall back to rule-based suggestions when AI is unavailable. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +## Conclusion +The Next Action Suggestion Engine blends rule-based logic, contextual analytics, and optional AI enhancement to deliver personalized, prioritized recommendations. By combining application status, market signals, and user behavior, it guides users toward effective next steps—whether preparing for interviews, following up strategically, improving applications, or pivoting tactics. Its modular design supports customization and scalability while maintaining responsiveness and clarity. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices +- Glossary: + - Candidate action: A potential next step generated by the engine. + - Composite score: Weighted aggregation of signals determining action priority. + - Red flag: Risk indicator that may trigger urgent or alternative strategies. +- Configuration tips: + - Tune weights in the scoring module to reflect user goals. + - Adjust follow-up windows in the follow-ups module to match industry norms. + - Enable AI assistance selectively to balance quality and latency. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/AI Integration System.md b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/AI Integration System.md new file mode 100644 index 0000000..e91930e --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/AI Integration System.md @@ -0,0 +1,425 @@ +# AI Integration System + + +**Referenced Files in This Document** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the AI integration system in ApplyGuard PH, focusing on how the frontend communicates with Supabase Edge Functions to perform AI processing via a proxy architecture. It covers request/response handling, prompt engineering strategies for resume analysis, interview preparation, and content evaluation, as well as error handling patterns, retry mechanisms, fallback strategies, configuration options for different models/providers, and examples of prompt templates and response parsing logic. + +## Project Structure +The AI integration spans client-side libraries and components, and server-side Edge Functions: +- Client-side: + - lib/ai.js: Orchestrates AI calls, retries, and fallbacks. + - lib/prompt.js: Builds prompts for various tasks (resume analysis, interview prep, content evaluation). + - lib/analyze.js: Parses and normalizes AI responses into structured data. + - components/AiAssistant.jsx and components/MockInterviewPage.jsx: UI flows that trigger AI features. +- Server-side: + - supabase/functions/ai-proxy/index.ts: Secure proxy to external AI providers. + - supabase/functions/_shared/prompts.ts: Shared prompt templates and helpers. + - supabase/functions/_shared/http.ts: HTTP utilities for provider requests. + - supabase/functions/_shared/entitlement.ts: Entitlement checks before invoking AI. + +```mermaid +graph TB +subgraph "Frontend" +A["AiAssistant.jsx"] +B["MockInterviewPage.jsx"] +C["lib/ai.js"] +D["lib/prompt.js"] +E["lib/analyze.js"] +end +subgraph "Supabase Edge Functions" +F["ai-proxy/index.ts"] +G["_shared/prompts.ts"] +H["_shared/http.ts"] +I["_shared/entitlement.ts"] +end +A --> C +B --> C +C --> D +C --> E +C --> F +F --> G +F --> H +F --> I +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Core Components +- ai.js + - Purpose: Central client orchestrator for AI operations. Handles building payloads, calling the Edge Function proxy, retrying transient failures, and parsing structured outputs. + - Key responsibilities: + - Construct request bodies with task type, context, and parameters. + - Manage timeouts, retries, and backoff. + - Normalize responses using analyze.js. + - Surface user-friendly errors and fallback results when needed. +- prompt.js + - Purpose: Composes prompts for specific tasks such as resume analysis, mock interview generation, and content evaluation. + - Key responsibilities: + - Select appropriate template based on task. + - Inject dynamic variables (e.g., resume text, job description, candidate profile). + - Enforce constraints like output format hints. +- analyze.js + - Purpose: Parses raw AI outputs into consistent structures consumed by UI and downstream logic. + - Key responsibilities: + - Validate fields and coerce types. + - Provide defaults or partial results when parsing fails. + - Map provider-specific formats to a unified schema. +- AiAssistant.jsx and MockInterviewPage.jsx + - Purpose: User-facing flows that initiate AI tasks and render results. + - Key responsibilities: + - Collect inputs and display progress. + - Handle loading states, errors, and retry actions. + - Render parsed results from analyze.js. +- ai-proxy/index.ts + - Purpose: Secure server-side proxy that authenticates calls, enforces entitlements, and forwards requests to configured AI providers. + - Key responsibilities: + - Validate incoming requests and headers. + - Check entitlements before proceeding. + - Build provider-specific requests using http.ts and prompts.ts. + - Stream or buffer responses and return normalized JSON. +- _shared/prompts.ts + - Purpose: Centralized prompt templates and helpers used by the proxy. +- _shared/http.ts + - Purpose: HTTP client utilities for making provider API calls with retries and timeouts. +- _shared/entitlement.ts + - Purpose: Validates user entitlements (e.g., subscription status) before allowing AI usage. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Architecture Overview +The system uses a secure proxy pattern: +- Frontend calls a Supabase Edge Function endpoint. +- The proxy validates entitlements, constructs provider requests, and returns structured responses. +- Prompt templates are centralized and reused across tasks. +- Response parsing is standardized on the client side. + +```mermaid +sequenceDiagram +participant UI as "AiAssistant.jsx / MockInterviewPage.jsx" +participant ClientAI as "lib/ai.js" +participant Proxy as "ai-proxy/index.ts" +participant Entitle as "_shared/entitlement.ts" +participant Prompts as "_shared/prompts.ts" +participant HTTP as "_shared/http.ts" +participant Provider as "External AI Provider" +UI->>ClientAI : "Start AI task" +ClientAI->>Proxy : "POST /ai-proxy {task, params}" +Proxy->>Entitle : "Check entitlements" +Entitle-->>Proxy : "Allowed/Denied" +Proxy->>Prompts : "Build prompt for task" +Prompts-->>Proxy : "Prompt payload" +Proxy->>HTTP : "Call provider API" +HTTP->>Provider : "Request" +Provider-->>HTTP : "Response" +HTTP-->>Proxy : "Normalized result" +Proxy-->>ClientAI : "Structured JSON" +ClientAI->>ClientAI : "Parse with analyze.js" +ClientAI-->>UI : "Rendered result" +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Detailed Component Analysis + +### Client AI Orchestration (lib/ai.js) +- Responsibilities: + - Build request payloads including task identifiers and parameters. + - Call the Edge Function proxy with proper headers and timeouts. + - Implement retry with exponential backoff for transient errors (network timeouts, rate limits). + - Parse responses using analyze.js and provide fallbacks when parsing fails. +- Error handling: + - Distinguish between network errors, provider errors, and parsing errors. + - Surface actionable messages to users and log diagnostic details. +- Configuration: + - Supports selecting different models/providers via parameters. + - Allows tuning temperature, max tokens, and other model-specific options. + +```mermaid +flowchart TD +Start(["Start AI Task"]) --> BuildPayload["Build Payload
task + params"] +BuildPayload --> CallProxy["Call ai-proxy/index.ts"] +CallProxy --> Success{"Success?"} +Success --> |Yes| Parse["Parse with analyze.js"] +Parse --> Render["Return structured result"] +Success --> |No| RetryCount{"Retry attempts < limit?"} +RetryCount --> |Yes| Backoff["Exponential backoff"] +Backoff --> CallProxy +RetryCount --> |No| Fallback["Use fallback strategy"] +Fallback --> Render +``` + +**Diagram sources** +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) + +### Prompt Engineering (lib/prompt.js and _shared/prompts.ts) +- Strategies: + - Use task-specific templates for resume analysis, interview preparation, and content evaluation. + - Include explicit instructions for output structure to simplify parsing. + - Inject contextual variables (resume text, job description, candidate profile) safely. +- Templates: + - Centralized in _shared/prompts.ts for reuse and consistency. + - Parameterized to support multiple models/providers. +- Best practices: + - Keep prompts concise and focused. + - Provide examples within prompts where helpful. + - Avoid leaking sensitive information; sanitize inputs. + +```mermaid +classDiagram +class PromptBuilder { ++buildResumeAnalysis(resume, jobDesc) ++buildInterviewPrep(profile, role) ++buildContentEvaluation(text, criteria) +} +class TemplateStore { ++getTemplate(task) ++render(template, vars) +} +PromptBuilder --> TemplateStore : "uses" +``` + +**Diagram sources** +- [prompt.js](file://src/lib/prompt.js) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [prompt.js](file://src/lib/prompt.js) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Response Parsing (lib/analyze.js) +- Responsibilities: + - Validate and coerce fields to expected types. + - Provide default values for missing fields. + - Map provider-specific schemas to a unified internal format. +- Robustness: + - Gracefully handle malformed responses. + - Return partial results when possible and flag issues for logging. + +```mermaid +flowchart TD +Raw["Raw AI Response"] --> Validate["Validate Fields"] +Validate --> Coerce["Coerce Types"] +Coerce --> Defaults["Apply Defaults"] +Defaults --> Unified["Map to Unified Schema"] +Unified --> Output["Structured Result"] +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Edge Function Proxy (supabase/functions/ai-proxy/index.ts) +- Responsibilities: + - Validate incoming requests and headers. + - Check entitlements before proceeding. + - Build provider-specific requests using shared modules. + - Return normalized JSON responses. +- Security: + - Enforce access control and rate limiting at the edge. + - Sanitize inputs and avoid exposing secrets. + +```mermaid +sequenceDiagram +participant Client as "lib/ai.js" +participant Proxy as "ai-proxy/index.ts" +participant Entitle as "_shared/entitlement.ts" +participant Prompts as "_shared/prompts.ts" +participant HTTP as "_shared/http.ts" +participant Provider as "External AI Provider" +Client->>Proxy : "POST /ai-proxy" +Proxy->>Entitle : "Verify entitlement" +Entitle-->>Proxy : "OK/Deny" +Proxy->>Prompts : "Resolve prompt" +Prompts-->>Proxy : "Prompt payload" +Proxy->>HTTP : "Invoke provider" +HTTP->>Provider : "API call" +Provider-->>HTTP : "Response" +HTTP-->>Proxy : "Result" +Proxy-->>Client : "Normalized JSON" +``` + +**Diagram sources** +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +### UI Flows (components/AiAssistant.jsx and components/MockInterviewPage.jsx) +- Responsibilities: + - Trigger AI tasks and manage UI state (loading, success, error). + - Display parsed results and allow retry actions. + - Collect user inputs and pass them to lib/ai.js. + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) + +## Dependency Analysis +The following diagram shows key dependencies among core files: + +```mermaid +graph LR +AiAssistant["AiAssistant.jsx"] --> AI["lib/ai.js"] +MockInterview["MockInterviewPage.jsx"] --> AI +AI --> Prompt["lib/prompt.js"] +AI --> Analyze["lib/analyze.js"] +AI --> Proxy["ai-proxy/index.ts"] +Proxy --> Entitle["_shared/entitlement.ts"] +Proxy --> Prompts["_shared/prompts.ts"] +Proxy --> HTTP["_shared/http.ts"] +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) + +## Performance Considerations +- Prefer streaming responses from providers when available to reduce perceived latency. +- Cache reusable prompt templates and frequently accessed metadata on the client. +- Tune retry backoff and maximum attempts to balance responsiveness and resilience. +- Limit input sizes to reduce token usage and costs. +- Use efficient parsing and avoid unnecessary re-renders in UI components. + +## Troubleshooting Guide +Common issues and resolutions: +- Network timeouts or intermittent failures: + - Verify retry settings and backoff intervals in lib/ai.js. + - Check Edge Function logs for upstream provider errors. +- Rate limiting or quota exceeded: + - Adjust concurrency and retry policies. + - Monitor entitlements and usage quotas in _shared/entitlement.ts. +- Malformed responses: + - Inspect parsing logic in lib/analyze.js and add robust defaults. + - Log raw responses for diagnostics while avoiding sensitive data exposure. +- Prompt-related errors: + - Validate prompt templates in _shared/prompts.ts and ensure all required variables are provided. + - Test prompts with representative inputs to catch edge cases. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) + +## Conclusion +The AI integration in ApplyGuard PH leverages a secure proxy architecture to centralize provider interactions, enforce entitlements, and standardize prompt construction and response parsing. The client-side orchestration provides resilient retry and fallback mechanisms, while the server-side proxy ensures security and consistency. By centralizing prompt templates and response normalization, the system remains maintainable and adaptable to different AI models and providers. + +## Appendices + +### Example Prompt Templates +- Resume analysis: + - Inputs: resume text, optional job description. + - Output: structured feedback with strengths, gaps, and recommendations. +- Interview preparation: + - Inputs: candidate profile, target role. + - Output: tailored questions and suggested answers. +- Content evaluation: + - Inputs: text to evaluate, evaluation criteria. + - Output: scored assessment with explanations. + +For concrete template definitions, see: +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Configuration Options +- Model/provider selection: + - Configure via parameters passed to lib/ai.js and resolved in the proxy. +- Request tuning: + - Temperature, max tokens, and other provider-specific options can be included in payloads. +- Retry and fallback: + - Adjust retry counts, backoff multipliers, and fallback behaviors in lib/ai.js. + +References: +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Content Parsing Engine.md b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Content Parsing Engine.md new file mode 100644 index 0000000..66241e2 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Content Parsing Engine.md @@ -0,0 +1,346 @@ +# Content Parsing Engine + + +**Referenced Files in This Document** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [samples.js](file://src/lib/samples.js) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the content parsing engine used by ApplyGuard PH to extract structured information from unstructured resume text. It covers how skills, experience timelines, education, and achievements are recognized; the regex patterns, NLP techniques, and heuristic algorithms applied; input formats and parsing rules; output data structures; validation and error handling; and support for different resume formats and layouts. + +The parsing pipeline is implemented as a modular set of utilities that: +- Normalize and segment raw resume text into logical sections +- Identify entities such as skills, roles, organizations, dates, and degrees +- Quantify achievements where possible +- Validate extracted fields and produce a normalized result object +- Provide scoring, red flags, missing items, and next actions based on the parsed data + +## Project Structure +At a high level, the parsing logic resides under src/lib with UI integration points in src/components. The main flow is: +- User uploads or pastes resume text via ScanForm +- analyze.js orchestrates parsing and normalization +- ai.js and prompt.js provide AI-assisted extraction when needed +- Supporting modules (scoring, redflags, missing, nextaction, stats) consume the parsed result to generate insights +- ResultView renders the final structured output + +```mermaid +graph TB +UI["ScanForm.jsx"] --> Analyzer["analyze.js"] +Analyzer --> AINLP["ai.js"] +Analyzer --> Prompts["prompt.js"] +Analyzer --> Skills["skills extraction"] +Analyzer --> Timeline["timeline parsing"] +Analyzer --> Education["education extraction"] +Analyzer --> Achievements["achievement quantification"] +Analyzer --> Validator["validation & normalization"] +Validator --> Output["Parsed Resume Object"] +Output --> Scoring["scoring.js"] +Output --> RedFlags["redflags.js"] +Output --> Missing["missing.js"] +Output --> NextAction["nextaction.js"] +Output --> Stats["stats.js"] +UI --> ResultView["ResultView.jsx"] +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Core Components +- Text normalization and segmentation: tokenization, section detection, and line-level heuristics +- Entity recognition: skills, job titles, companies, locations, dates, degrees, institutions +- Achievement quantification: numeric extraction, metric inference, and unit normalization +- Validation and normalization: type coercion, range checks, deduplication, and canonical forms +- Optional AI assistance: LLM-based extraction guided by prompts for ambiguous cases +- Post-processing: scoring, red flag detection, missing item analysis, next action suggestions, and statistics + +Key responsibilities and interactions are implemented across the following files: +- analyze.js: central orchestration of parsing steps and normalization +- ai.js and prompt.js: optional AI-assisted extraction and prompt templates +- scoring.js, redflags.js, missing.js, nextaction.js, stats.js: downstream analytics and guidance +- ScanForm.jsx and ResultView.jsx: user-facing entry and display points + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +The parsing engine follows a layered architecture: +- Input layer: accepts plain text, PDF-derived text, or HTML snippets +- Preprocessing layer: cleans whitespace, normalizes punctuation, splits into lines/blocks +- Recognition layer: applies regex patterns and heuristics to detect sections and entities +- Normalization layer: standardizes values (dates, durations, units), deduplicates, and validates +- Optional AI layer: uses ai.js and prompt.js to resolve ambiguities or enrich sparse inputs +- Analytics layer: scoring, red flags, missing items, next actions, and summary statistics +- Output layer: produces a structured JSON-like object consumed by UI components + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "ScanForm.jsx" +participant Analyzer as "analyze.js" +participant AI as "ai.js / prompt.js" +participant Analytics as "scoring.js / redflags.js / missing.js / nextaction.js / stats.js" +participant View as "ResultView.jsx" +User->>UI : Paste or upload resume text +UI->>Analyzer : normalizeAndParse(text) +Analyzer->>Analyzer : preprocess(text) +Analyzer->>Analyzer : detectSections() +Analyzer->>Analyzer : extractSkills() +Analyzer->>Analyzer : parseTimeline() +Analyzer->>Analyzer : extractEducation() +Analyzer->>Analyzer : quantifyAchievements() +Analyzer->>AI : optional enrichment for ambiguous cases +AI-->>Analyzer : enriched entities +Analyzer->>Analyzer : validateAndNormalize() +Analyzer-->>UI : parsedResume +UI->>Analytics : computeScore(parsedResume) +UI->>Analytics : detectRedFlags(parsedResume) +UI->>Analytics : findMissing(parsedResume) +UI->>Analytics : suggestNextActions(parsedResume) +UI->>Analytics : computeStats(parsedResume) +UI->>View : render(parsedResume + analytics) +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Detailed Component Analysis + +### Section Detection and Text Segmentation +- Purpose: Convert raw resume text into coherent blocks representing contact info, summary, experience, education, skills, projects, certifications, and other sections. +- Techniques: + - Line splitting and blank-line grouping + - Header heuristics using capitalized phrases and common keywords + - Regex anchors for known section titles and separators +- Output: Ordered list of sections with metadata (title, start/end indices, confidence). + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Skills Identification +- Purpose: Extract technical and soft skills from unstructured text. +- Techniques: + - Keyword dictionaries and synonym mapping + - Regex patterns for skill lists, bullet points, and inline mentions + - Contextual heuristics (e.g., “Proficient in”, “Experience with”) + - Deduplication and normalization (case folding, pluralization) +- Output: Array of canonical skill tokens with counts and contexts. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Experience Timeline Parsing +- Purpose: Build a chronological timeline of roles, organizations, locations, and date ranges. +- Techniques: + - Date pattern recognition (month-year, year-only, ranges) + - Role/title extraction via title heuristics and capitalization + - Organization name extraction near role entries + - Duration calculation and overlap resolution +- Output: List of experience objects with standardized date ranges and computed durations. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Education Extraction +- Purpose: Identify degrees, institutions, majors, graduation years, and honors. +- Techniques: + - Degree keyword matching (BSc, MSc, PhD, BA, etc.) + - Institution name heuristics and location cues + - Year extraction and validation against realistic ranges +- Output: List of education objects with degree, institution, major, and year. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Achievement Quantification +- Purpose: Detect and quantify achievements expressed in bullets or descriptions. +- Techniques: + - Numeric extraction (percentages, currency, counts, timeframes) + - Metric inference (e.g., “increased sales by X%” → {metric: “sales”, change: “increase”, value: X, unit: “%”}) + - Unit normalization and aggregation +- Output: Structured achievement records with metrics, units, and context references. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Validation and Normalization +- Purpose: Ensure consistency, correctness, and completeness of extracted data. +- Techniques: + - Type coercion (strings to numbers, dates to ISO format) + - Range checks (e.g., graduation year within plausible bounds) + - Deduplication and canonicalization (skill names, organization names) + - Error tagging for fields that failed validation +- Output: Validated parsedResume object with warnings and errors. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Optional AI-Assisted Extraction +- Purpose: Improve accuracy for ambiguous or poorly formatted resumes. +- Techniques: + - ai.js orchestrates calls to an external model + - prompt.js provides structured prompts tailored to each extraction task + - Fallback to deterministic methods when AI is unavailable or fails +- Output: Enriched entities and resolved ambiguities merged back into parsedResume. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +### Downstream Analytics +- Scoring: Summarizes candidate strength based on skills, experience depth, education, and achievements. +- Red Flags: Identifies inconsistencies, gaps, or risky signals (e.g., unrealistic durations). +- Missing Items: Highlights absent but desirable elements (e.g., missing contact info, incomplete education). +- Next Actions: Suggests improvements or follow-ups (e.g., add quantified achievements). +- Stats: Provides summary counts and distributions (e.g., number of skills, average tenure). + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) + +### UI Integration +- ScanForm.jsx: Accepts resume input, triggers parsing, and displays progress/errors. +- ResultView.jsx: Renders parsedResume and analytics results in a readable layout. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Dependency Analysis +The parsing engine exhibits clear separation of concerns: +- analyze.js depends on ai.js and prompt.js for optional enrichment +- Downstream analytics depend only on the validated parsedResume object +- UI components depend on analyze.js outputs and analytics results + +```mermaid +graph LR +Analyze["analyze.js"] --> AI["ai.js"] +Analyze --> Prompt["prompt.js"] +Analyze --> Score["scoring.js"] +Analyze --> RedFlags["redflags.js"] +Analyze --> Missing["missing.js"] +Analyze --> NextAction["nextaction.js"] +Analyze --> Stats["stats.js"] +UI["ScanForm.jsx"] --> Analyze +UI --> ResultView["ResultView.jsx"] +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Performance Considerations +- Prefer deterministic regex and heuristics over AI calls to reduce latency and cost +- Cache skill dictionaries and common patterns to avoid recomputation +- Stream processing for large texts: chunking and incremental normalization +- Limit AI fallbacks to ambiguous segments identified by low-confidence detections +- Defer heavy analytics until after core parsing completes + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Malformed dates: Ensure date patterns cover regional formats; validate ranges and coerce to ISO strings +- Overlapping experiences: Resolve overlaps by prioritizing most recent or longest duration +- Duplicate skills: Normalize synonyms and deduplicate before scoring +- Missing sections: If section detection fails, trigger AI-assisted enrichment +- Empty or invalid input: Return explicit errors and guide users to reformat or paste clean text + +Error handling strategies: +- Tag fields with warnings/errors during validation +- Provide fallback defaults for non-critical fields +- Log detailed diagnostics for debugging without exposing sensitive data + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +## Conclusion +ApplyGuard PH’s content parsing engine combines robust regex-based heuristics with optional AI assistance to transform unstructured resume text into a normalized, validated, and analyzable data structure. By separating preprocessing, recognition, normalization, and analytics, the system remains maintainable, extensible, and performant across diverse resume formats and layouts. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Input Formats Supported +- Plain text resumes (copied from PDFs or Word documents) +- HTML snippets with minimal markup +- Mixed layouts with varied headings and bullet styles + +### Parsing Rules Summary +- Section headers: Recognize common titles and separators; allow flexible casing and punctuation +- Dates: Support month-year, year-only, and ranges; normalize to consistent formats +- Skills: Use curated dictionaries and contextual cues; normalize plurals and synonyms +- Achievements: Extract numbers and units; infer metrics and directionality (increase/decrease) + +### Output Data Structures +- parsedResume: Top-level object containing normalized sections and entities +- experience[]: Objects with role, organization, location, dateRange, and computed duration +- education[]: Objects with degree, institution, major, and year +- skills[]: Canonicalized skill tokens with counts and contexts +- achievements[]: Structured records with metrics, units, and references +- validation: Warnings and errors per field for transparency + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Resume Analysis Engine.md b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Resume Analysis Engine.md new file mode 100644 index 0000000..01d061f --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Resume Analysis Engine.md @@ -0,0 +1,376 @@ +# Resume Analysis Engine + + +**Referenced Files in This Document** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the resume analysis engine used by ApplyGuard PH to parse resumes, extract key information, evaluate content quality, and generate actionable insights. It covers: +- AI-powered scanning algorithms and orchestration +- Tone analysis system for communication style, confidence, and professional language patterns +- Content evaluation methods including scoring and red flag detection +- AI integration patterns (client-side orchestration and server proxy), prompt engineering approaches, and response processing +- Configuration options for different industries or job types and customization points for specific criteria + +## Project Structure +The resume analysis engine is implemented primarily in client-side libraries with a server-side AI proxy for secure LLM calls. Key modules: +- Orchestration and parsing: src/lib/analyze.js +- AI orchestration and response handling: src/lib/ai.js +- Prompt composition and templates: src/lib/prompt.js +- Tone analysis: src/lib/tone.js +- Scoring and metrics: src/lib/scoring.js +- Red flag detection: src/lib/redflags.js +- Server-side AI proxy: supabase/functions/ai-proxy/index.ts +- Shared prompts on server: supabase/functions/_shared/prompts.ts + +```mermaid +graph TB +subgraph "Client Libraries" +A["analyze.js"] +B["ai.js"] +C["prompt.js"] +D["tone.js"] +E["scoring.js"] +F["redflags.js"] +end +subgraph "Serverless Functions" +G["ai-proxy/index.ts"] +H["_shared/prompts.ts"] +end +A --> B +A --> C +A --> D +A --> E +A --> F +B --> G +G --> H +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Core Components +- analyze.js: Orchestrates resume ingestion, parsing, extraction, tone analysis, scoring, and insight generation. Coordinates between local heuristics and AI-driven steps. +- ai.js: Encapsulates AI invocation patterns, request shaping, retries, timeouts, and response normalization. +- prompt.js: Composes prompts for different analysis tasks (e.g., extraction, tone, scoring). Supports context injection such as industry or role type. +- tone.js: Implements tone analysis algorithms to detect communication style, confidence levels, and professional language patterns. +- scoring.js: Aggregates signals into scores and grades across dimensions like relevance, clarity, impact, and professionalism. +- redflags.js: Detects potential issues (e.g., inconsistencies, missing sections, overly generic statements) and flags them for review. +- ai-proxy/index.ts: Secure server-side proxy that forwards requests to the LLM provider, enforces policies, and returns structured responses. +- _shared/prompts.ts: Centralized prompt templates and constants used by both client and server components. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Architecture Overview +High-level flow: +- The client composes prompts and prepares resume text. +- Local heuristics run first (parsing, tone, red flags). +- For AI-dependent steps, the client uses ai.js to call the server proxy. +- The server proxy invokes the LLM using shared prompts and returns normalized results. +- The client aggregates outputs into final insights and scores. + +```mermaid +sequenceDiagram +participant Client as "Client App" +participant Analyzer as "analyze.js" +participant Tone as "tone.js" +participant Flags as "redflags.js" +participant Score as "scoring.js" +participant AI as "ai.js" +participant Proxy as "ai-proxy/index.ts" +participant Prompts as "_shared/prompts.ts" +Client->>Analyzer : "Submit resume text + config" +Analyzer->>Analyzer : "Parse and normalize" +Analyzer->>Tone : "Analyze tone" +Analyzer->>Flags : "Detect red flags" +Analyzer->>AI : "Request AI analysis (extraction/score)" +AI->>Proxy : "Forward request" +Proxy->>Prompts : "Load prompt template" +Proxy-->>AI : "LLM response" +AI-->>Analyzer : "Normalized result" +Analyzer->>Score : "Aggregate scores" +Analyzer-->>Client : "Insights and recommendations" +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Detailed Component Analysis + +### Orchestration and Parsing (analyze.js) +Responsibilities: +- Ingest raw resume text and optional metadata (industry, target role). +- Normalize input (whitespace, encoding, section boundaries). +- Coordinate local analyses (tone, red flags) and AI calls. +- Merge AI outputs with heuristic results into a unified report. +- Provide configuration hooks for domain-specific behavior. + +Key behaviors: +- Deterministic preprocessing before any AI call to reduce noise. +- Parallelization where safe (e.g., tone and red flags can run concurrently). +- Robust error handling and fallbacks when AI is unavailable. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### AI Integration Patterns (ai.js) +Responsibilities: +- Build requests for AI tasks (extraction, evaluation, suggestions). +- Manage retries, timeouts, and backoff strategies. +- Normalize heterogeneous LLM responses into a consistent schema. +- Surface errors and partial results gracefully. + +Patterns: +- Request shaping via prompt templates from prompt.js. +- Strict validation of returned structures to ensure downstream stability. +- Optional caching of repeated queries based on inputs. + +**Section sources** +- [ai.js](file://src/lib/ai.js) + +### Prompt Engineering (prompt.js and _shared/prompts.ts) +Responsibilities: +- Define reusable prompt templates for extraction, tone, scoring, and recommendations. +- Inject contextual variables (industry, role, experience level). +- Enforce output schemas to simplify parsing. + +Approach: +- Template-based composition with placeholders for dynamic fields. +- Versioning and environment-aware overrides via shared prompts. +- Clear instructions for model behavior and constraints. + +**Section sources** +- [prompt.js](file://src/lib/prompt.js) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Tone Analysis System (tone.js) +Algorithms: +- Communication style detection (formal vs informal, assertive vs tentative). +- Confidence level estimation based on linguistic markers and phrasing. +- Professional language pattern recognition (action verbs, quantified outcomes, jargon usage). +- Consistency checks across sections (summary vs experience bullets). + +Outputs: +- Style profile and confidence score. +- Actionable tips to improve tone and professionalism. + +**Section sources** +- [tone.js](file://src/lib/tone.js) + +### Content Evaluation and Scoring (scoring.js) +Dimensions: +- Relevance to target role/industry. +- Clarity and structure. +- Impact and achievement orientation. +- Professionalism and tone alignment. + +Mechanics: +- Weighted aggregation of signals from heuristics and AI. +- Normalization to consistent scales. +- Thresholds and grading bands for readability. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) + +### Red Flag Detection (redflags.js) +Checks: +- Missing critical sections (e.g., contact info, summary). +- Inconsistencies (dates, roles, locations). +- Overly generic statements without metrics. +- Formatting anomalies and excessive length. + +Outputs: +- List of flagged items with severity and suggested fixes. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) + +### Server-Side AI Proxy (ai-proxy/index.ts) +Responsibilities: +- Receive client requests and validate payloads. +- Load appropriate prompt templates from shared prompts. +- Call the LLM provider securely and return normalized responses. +- Enforce rate limits and logging for observability. + +Security and reliability: +- Input sanitization and size limits. +- Retry and timeout handling at the edge. +- Structured error responses for client consumption. + +**Section sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### End-to-End Flow Diagram +```mermaid +flowchart TD +Start(["Resume Submitted"]) --> Preprocess["Preprocess and Normalize"] +Preprocess --> LocalAnalysis["Run Local Analyses
Tone + Red Flags"] +LocalAnalysis --> DecideAI{"AI Needed?"} +DecideAI --> |Yes| BuildPrompt["Compose Prompt via prompt.js"] +BuildPrompt --> CallProxy["Call ai-proxy/index.ts"] +CallProxy --> Normalize["Normalize Response"] +DecideAI --> |No| SkipAI["Skip AI Step"] +Normalize --> Aggregate["Aggregate Scores via scoring.js"] +SkipAI --> Aggregate +Aggregate --> Report["Generate Insights and Recommendations"] +Report --> End(["Deliver Results"]) +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [scoring.js](file://src/lib/scoring.js) +- [tone.js](file://src/lib/tone.js) +- [redflags.js](file://src/lib/redflags.js) + +## Dependency Analysis +Internal dependencies: +- analyze.js depends on ai.js, prompt.js, tone.js, scoring.js, and redflags.js. +- ai.js depends on prompt.js for request shaping and may rely on shared prompts via the proxy. +- ai-proxy/index.ts depends on _shared/prompts.ts for canonical templates. + +External dependencies: +- LLM provider invoked through the server proxy. +- Network layer for client-server communication. + +Potential risks: +- Tight coupling between prompt templates and response parsers; changes require coordinated updates. +- Reliance on network availability for AI steps; robust fallbacks are essential. + +```mermaid +graph LR +Analyze["analyze.js"] --> AI["ai.js"] +Analyze --> Prompt["prompt.js"] +Analyze --> Tone["tone.js"] +Analyze --> Score["scoring.js"] +Analyze --> Flags["redflags.js"] +AI --> Proxy["ai-proxy/index.ts"] +Proxy --> SharedPrompts["_shared/prompts.ts"] +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) + +## Performance Considerations +- Prefer local heuristics (tone, red flags) to minimize costly AI calls. +- Batch or deduplicate identical AI requests where possible. +- Use streaming or chunked processing for large resumes if supported by the proxy. +- Cache frequent prompt templates and common configurations. +- Implement exponential backoff and circuit breakers for AI calls. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- AI call failures: Check proxy logs, verify prompt templates, and confirm network connectivity. Ensure retries and timeouts are configured appropriately. +- Malformed responses: Validate response schemas early in ai.js and add defensive parsing. +- Inconsistent tone scores: Review tone.js rules and adjust thresholds based on feedback. +- Excessive red flags: Tune redflags.js sensitivity and consider context-aware overrides. + +Operational tips: +- Enable detailed logging around AI request/response cycles. +- Add unit tests for prompt variations and response shapes. +- Monitor latency and error rates at the proxy layer. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [tone.js](file://src/lib/tone.js) +- [redflags.js](file://src/lib/redflags.js) + +## Conclusion +The resume analysis engine combines deterministic heuristics with AI-driven insights to deliver comprehensive evaluations. By separating concerns across parsing, tone analysis, red flag detection, scoring, and AI orchestration, the system remains maintainable and extensible. The server-side proxy centralizes prompt management and security, while client-side modules provide flexibility for customization and rapid iteration. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Options and Customization Points +- Industry and role targeting: + - Provide industry and target role metadata to tailor prompts and scoring weights. +- Scoring weights: + - Adjust dimension weights in scoring.js to emphasize certain qualities (e.g., impact over clarity). +- Tone thresholds: + - Modify tone.js thresholds to align with organizational standards. +- Red flag rules: + - Extend redflags.js with domain-specific checks (e.g., certifications required for regulated roles). +- Prompt templates: + - Update prompt.js and _shared/prompts.ts to refine AI behavior and output schemas. + +**Section sources** +- [prompt.js](file://src/lib/prompt.js) +- [supabase/functions/_shared/prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [scoring.js](file://src/lib/scoring.js) +- [tone.js](file://src/lib/tone.js) +- [redflags.js](file://src/lib/redflags.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Tone Analysis Algorithms.md b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Tone Analysis Algorithms.md new file mode 100644 index 0000000..7891987 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Resume Analysis Engine/Tone Analysis Algorithms.md @@ -0,0 +1,359 @@ +# Tone Analysis Algorithms + + +**Referenced Files in This Document** +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [redflags.js](file://src/lib/redflags.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the tone analysis algorithms used by ApplyGuard PH to evaluate professional communication style, confidence levels, and language patterns in resumes and cover letters. It covers how positive/negative sentiment, assertiveness, and industry-specific terminology usage are scored, how results are interpreted, and how customization options adapt the analysis for different professional contexts. The document also describes how linguistic analysis integrates with the overall resume assessment pipeline. + +## Project Structure +The tone analysis feature is implemented primarily within the frontend library layer and integrated into the result view: +- src/lib/tone.js: Core tone scoring logic (sentiment, assertiveness, confidence, jargon detection). +- src/lib/scoring.js: Aggregation and normalization of sub-scores into final metrics. +- src/lib/analyze.js: Orchestrates analysis steps and composes outputs. +- src/lib/ai.js and src/lib/prompt.js: Optional AI-assisted prompts and responses for advanced tone insights. +- src/lib/redflags.js: Heuristics that can influence tone-related flags. +- src/components/ResultView.jsx: Renders tone scores and guidance to users. + +```mermaid +graph TB +A["analyze.js"] --> B["tone.js"] +A --> C["scoring.js"] +A --> D["redflags.js"] +A --> E["ai.js"] +E --> F["prompt.js"] +G["ResultView.jsx"] --> A +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [redflags.js](file://src/lib/redflags.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Core Components +- Tone scorer (tone.js): Computes sub-scores for sentiment polarity, assertiveness, confidence, and domain terminology density. It tokenizes text, applies rule-based heuristics, and optionally leverages AI-generated signals via ai.js and prompt.js. +- Scoring aggregator (scoring.js): Normalizes raw signals, weights them according to context (e.g., role or industry), and produces composite metrics such as Professionalism, Confidence, and Assertiveness. +- Analysis orchestrator (analyze.js): Coordinates input parsing, runs tone analysis, merges red flag checks, and returns a structured report consumed by ResultView.jsx. +- Red flags (redflags.js): Identifies problematic phrasing or patterns that may reduce tone quality (e.g., overly negative language, excessive hedging). +- UI integration (ResultView.jsx): Displays tone scores, explanations, and actionable recommendations. + +**Section sources** +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +The tone analysis pipeline processes resume or cover letter text through deterministic rules and optional AI assistance, then aggregates results into interpretable scores. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "ResultView.jsx" +participant Analyzer as "analyze.js" +participant Tone as "tone.js" +participant Score as "scoring.js" +participant Flags as "redflags.js" +participant AI as "ai.js" +participant Prompt as "prompt.js" +User->>UI : Submit resume/cover letter +UI->>Analyzer : analyze(text, options) +Analyzer->>Tone : computeTone(text, options) +Tone-->>Analyzer : {sentiment, assertiveness, confidence, jargon} +Analyzer->>Flags : checkRedFlags(text) +Flags-->>Analyzer : {redFlags[]} +Analyzer->>AI : optionalAIInsights(text, Prompt.buildPrompt(options)) +AI-->>Analyzer : {aiSignals?} +Analyzer->>Score : aggregate({tone, flags, aiSignals}, options) +Score-->>Analyzer : {Professionalism, Confidence, Assertiveness, ...} +Analyzer-->>UI : Report +UI-->>User : Display scores and guidance +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Detailed Component Analysis + +### Tone Scorer (tone.js) +Responsibilities: +- Sentiment polarity: Detects positive vs negative language using lexical cues and contextual modifiers. +- Assertiveness: Measures directness and certainty markers (e.g., strong verbs, quantifiers, definitive statements). +- Confidence: Evaluates self-referential strength, achievement framing, and avoidance of weak qualifiers. +- Industry terminology density: Counts domain-specific terms relative to total content length. + +Processing logic: +- Text normalization and segmentation into sentences/phrases. +- Lexicon lookups and regex-based pattern matching for sentiment and assertiveness. +- Weighting adjustments based on context (role type, industry tags). +- Optional enrichment from AI-assisted prompts when enabled. + +```mermaid +flowchart TD +Start(["Input text"]) --> Normalize["Normalize and segment text"] +Normalize --> Sentiment["Compute sentiment polarity"] +Normalize --> Assertive["Compute assertiveness score"] +Normalize --> Confidence["Compute confidence indicators"] +Normalize --> Jargon["Count industry terminology density"] +Sentiment --> Merge["Merge sub-scores"] +Assertive --> Merge +Confidence --> Merge +Jargon --> Merge +Merge --> Output(["Tone profile"]) +``` + +**Diagram sources** +- [tone.js](file://src/lib/tone.js) + +**Section sources** +- [tone.js](file://src/lib/tone.js) + +### Scoring Aggregator (scoring.js) +Responsibilities: +- Normalize raw sub-scores to consistent scales. +- Apply weighting per professional context (e.g., leadership roles emphasize assertiveness; technical roles emphasize clarity and terminology). +- Produce composite metrics: Professionalism, Confidence, Assertiveness, and optional Domain Fit. + +Normalization and weighting: +- Min-max or z-score normalization depending on distribution characteristics. +- Context-aware weights configurable via options passed from analyze.js. +- Penalty/bonus adjustments for red flags detected by redflags.js. + +```mermaid +classDiagram +class ScoringAggregator { ++normalize(rawScores) ++applyWeights(context) ++aggregate(toneProfile, flags, aiSignals) ++computeComposite() +} +class ToneProfile { ++sentiment ++assertiveness ++confidence ++jargonDensity +} +class RedFlags { ++items[] +} +class AISignals { ++insights? +} +ScoringAggregator --> ToneProfile : "consumes" +ScoringAggregator --> RedFlags : "adjusts" +ScoringAggregator --> AISignals : "optional" +``` + +**Diagram sources** +- [scoring.js](file://src/lib/scoring.js) + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) + +### Analysis Orchestrator (analyze.js) +Responsibilities: +- Coordinate inputs, run tone analysis, integrate red flags, and optionally call AI services. +- Build a unified report structure for consumption by ResultView.jsx. +- Support customization options (industry, role level, desired tone profile). + +Integration points: +- Calls tone.js for core linguistic analysis. +- Invokes redflags.js for heuristic checks. +- Uses ai.js and prompt.js for optional AI-enhanced insights. +- Delegates aggregation to scoring.js. + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant Analyzer as "analyze.js" +participant Tone as "tone.js" +participant Flags as "redflags.js" +participant AI as "ai.js" +participant Prompt as "prompt.js" +participant Score as "scoring.js" +Caller->>Analyzer : analyze(text, options) +Analyzer->>Tone : computeTone(text, options) +Analyzer->>Flags : checkRedFlags(text) +alt AI enabled +Analyzer->>Prompt : buildPrompt(options) +Analyzer->>AI : getInsights(prompt) +AI-->>Analyzer : aiSignals +end +Analyzer->>Score : aggregate(tone, flags, aiSignals) +Score-->>Analyzer : report +Analyzer-->>Caller : report +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Red Flags (redflags.js) +Responsibilities: +- Identify potentially detrimental language patterns (e.g., excessive hedging, negativity, vague claims). +- Provide structured flags that influence tone scores and recommendations. + +Impact on scoring: +- Red flags can reduce Professionalism or Confidence scores. +- May trigger targeted suggestions in the UI. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) + +### AI-Assisted Insights (ai.js and prompt.js) +Responsibilities: +- Construct prompts tailored to the user’s context and goals. +- Retrieve optional AI-generated insights to enrich tone analysis. + +Usage: +- Optional pathway invoked by analyze.js when AI features are enabled. +- Results merged into the final report alongside deterministic scores. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +### UI Integration (ResultView.jsx) +Responsibilities: +- Render tone scores, explanations, and recommendations. +- Allow users to adjust context options (industry, role level) to refine scoring. + +Display elements: +- Composite scores (Professionalism, Confidence, Assertiveness). +- Sub-scores breakdown (sentiment, assertiveness, confidence, jargon density). +- Actionable tips derived from red flags and low-scoring areas. + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Dependency Analysis +The following diagram shows key dependencies among modules involved in tone analysis: + +```mermaid +graph LR +ResultView["ResultView.jsx"] --> Analyze["analyze.js"] +Analyze --> Tone["tone.js"] +Analyze --> Scoring["scoring.js"] +Analyze --> RedFlags["redflags.js"] +Analyze --> AI["ai.js"] +AI --> Prompt["prompt.js"] +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Performance Considerations +- Deterministic scoring (tone.js, scoring.js, redflags.js) is lightweight and suitable for client-side execution. +- AI-assisted insights (ai.js) introduce network latency; consider caching or debouncing calls. +- Tokenization and lexicon lookups should be optimized for large documents; pre-segmentation and memoization can help. +- Avoid redundant re-analysis by caching results keyed on normalized input and options. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing or empty text: Ensure input validation before calling analyze.js. +- Unexpectedly low scores: Check red flags and adjust context options (industry, role level). +- Inconsistent terminology detection: Verify industry term lists and update lexicons if necessary. +- AI insights not appearing: Confirm AI feature toggle and network connectivity; fallback to deterministic scores. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) + +## Conclusion +ApplyGuard PH’s tone analysis combines rule-based linguistic heuristics with optional AI assistance to deliver robust, interpretable scores for professional communication. By normalizing sub-scores and applying context-aware weights, the system produces meaningful metrics—Professionalism, Confidence, and Assertiveness—that guide users toward stronger resumes and cover letters. Customization options ensure relevance across industries and roles, while red flag detection and UI integration provide actionable feedback. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Example Tone Scores and Interpretation Guidelines +- Professionalism (0–100): Reflects overall appropriateness and polish of language. Higher values indicate clear, respectful, and goal-oriented phrasing. +- Confidence (0–100): Captures self-assured framing and achievement emphasis. Low scores suggest overuse of hedging or passive constructions. +- Assertiveness (0–100): Measures directness and decisiveness. Very high values may imply aggression; balance with professionalism. +- Sentiment Polarity (-1 to +1): Negative values indicate pessimistic or critical tone; positive values reflect constructive, forward-looking language. +- Industry Terminology Density (0–1): Proportion of domain-specific terms; higher values suggest strong alignment with target field. + +Interpretation tips: +- Aim for balanced assertiveness paired with high professionalism. +- Use positive sentiment to convey enthusiasm without exaggeration. +- Increase terminology density only where relevant to the target role. + +[No sources needed since this section provides general guidance] + +### Customization Options +- Industry tag: Adjusts terminology detection and weightings for sector-specific vocabulary. +- Role level: Influences emphasis on leadership language and strategic framing. +- Desired tone profile: Allows prioritization of assertiveness vs. diplomacy. +- AI insights toggle: Enables optional AI-assisted commentary. + +Configuration is typically passed via options to analyze.js and propagated to tone.js and scoring.js. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Red Flag Detection System.md b/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Red Flag Detection System.md new file mode 100644 index 0000000..7dc8896 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Red Flag Detection System.md @@ -0,0 +1,369 @@ +# Red Flag Detection System + + +**Referenced Files in This Document** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the red flag detection system in ApplyGuard PH, focusing on how job postings are analyzed to identify potential warning signs such as salary transparency issues, unrealistic expectations, poor culture indicators, and problematic employment terms. It details the pattern matching logic used to detect vague descriptions, excessive overtime requirements, lack of growth opportunities, and other concerning patterns. The document also covers severity classification, customization options for thresholds, integration with the overall scoring system, and actionable insights provided to job seekers. + +## Project Structure +The red flag detection system is implemented primarily in client-side JavaScript modules under src/lib, with UI components that present results and accept input. Key files include: +- Pattern definitions and detection logic +- Severity classification and risk scoring +- Integration with analysis orchestration and AI features +- UI components for scanning and result display + +```mermaid +graph TB +subgraph "Client Libraries" +RF["redflags.js"] +SC["scoring.js"] +AN["analyze.js"] +PR["prompt.js"] +AI["ai.js"] +end +subgraph "UI Components" +RV["ResultView.jsx"] +SF["ScanForm.jsx"] +end +SF --> AN +AN --> RF +AN --> SC +AN --> AI +AN --> PR +SC --> RV +RF --> RV +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +## Core Components +- Red flag detectors: Define categories (e.g., compensation, workload, culture, growth), rules, and severity levels. They scan text fields from a job posting and return flagged items with context and confidence. +- Scoring engine: Aggregates red flags into an overall score, applies weights by category and severity, and produces a risk profile with explanations. +- Orchestration layer: Coordinates parsing, rule evaluation, optional AI-assisted checks, and final report generation. +- UI integration: Presents detected red flags, severity, and recommendations to users. + +Key responsibilities: +- Pattern matching against structured and unstructured text +- Normalization and tokenization strategies +- Threshold-based activation and severity mapping +- Score aggregation and explanation generation +- User-facing summaries and next actions + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +The red flag detection pipeline processes job posting content through deterministic rules and optional AI assistance, then aggregates findings into a unified risk assessment. + +```mermaid +sequenceDiagram +participant User as "User" +participant ScanForm as "ScanForm.jsx" +participant Analyzer as "analyze.js" +participant Rules as "redflags.js" +participant Scorer as "scoring.js" +participant AI as "ai.js" +participant Prompt as "prompt.js" +participant Result as "ResultView.jsx" +User->>ScanForm : "Paste or upload job posting" +ScanForm->>Analyzer : "Submit text + metadata" +Analyzer->>Rules : "Run pattern detectors" +Rules-->>Analyzer : "List of red flags with severity" +Analyzer->>AI : "Optional AI verification/enrichment" +AI-->>Analyzer : "Enhanced signals (if enabled)" +Analyzer->>Scorer : "Aggregate flags and compute scores" +Scorer-->>Analyzer : "Score, risk level, explanations" +Analyzer-->>Result : "Rendered report" +Result-->>User : "Red flags, severity, insights" +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Detailed Component Analysis + +### Red Flag Detectors +The detector module defines categories and rules to identify warning signs across multiple dimensions: +- Compensation and benefits: Missing salary ranges, ambiguous pay structures, unpaid trial periods, unclear bonus/commission terms. +- Workload and schedule: Excessive overtime expectations, weekend/holiday work without compensation, vague “flexible hours” implying long hours. +- Culture and environment: Language indicating high pressure, blame culture, lack of feedback mechanisms, discriminatory phrasing. +- Growth and development: No mention of training, mentorship, career paths, or skill development. +- Employment terms: Probationary traps, non-compete clauses, unilateral change rights, lack of leave policies. + +Detection methods: +- Keyword and phrase matching with normalization (case-insensitive, punctuation handling). +- Regex patterns for numeric ranges, percentages, and time units. +- Contextual heuristics (e.g., absence of expected sections like “Compensation”). +- Confidence scoring based on match strength and contextual cues. + +Severity classification: +- Critical: Immediate disqualifiers (e.g., illegal practices, explicit discrimination, unpaid mandatory work). +- High: Strong indicators of risk (e.g., no salary range, excessive overtime language). +- Medium: Moderate concerns (e.g., vague growth opportunities, weak benefits). +- Low: Minor observations (e.g., missing optional perks). + +Customization options: +- Category weights to emphasize certain risks. +- Thresholds per category to tune sensitivity. +- Toggleable detectors (e.g., enable/disable AI-assisted checks). +- Custom keyword lists and regex patterns. + +Examples of detected issues and risk levels: +- “Salary not disclosed” → High severity; contributes significantly to overall risk. +- “Must be willing to work weekends without extra pay” → Critical severity; strong negative signal. +- “No clear promotion path mentioned” → Medium severity; indicates limited growth visibility. +- “Flexible hours” without further detail → Low severity; may imply long hours depending on context. + +Integration with scoring: +- Each red flag carries a weight derived from its severity and category importance. +- Scores are normalized to a consistent scale and combined into an overall risk score. +- Explanations link specific flags to their impact on the final score. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) + +#### Class Diagram: Detector Model +```mermaid +classDiagram +class RedFlag { ++string category ++string message ++number severity ++number confidence ++string[] evidence +} +class Detector { ++string name ++string[] keywords ++regex[] patterns ++function evaluate(text) RedFlag[] +} +class Scorer { ++object categoryWeights ++number threshold ++function aggregate(flags) Score +} +RedFlag <.. Detector : "produced by" +Scorer --> RedFlag : "consumes" +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) + +### Scoring Engine +The scoring engine transforms raw red flags into a unified risk profile: +- Weighted aggregation: Applies category-specific weights and severity multipliers. +- Thresholding: Determines pass/fail or tiered risk levels based on configured thresholds. +- Explanation generation: Maps aggregated scores back to actionable insights and recommended next steps. +- Normalization: Ensures scores are comparable across different postings and configurations. + +Configuration inputs: +- Category weights (e.g., compensation > culture > growth). +- Severity-to-weight mapping. +- Global thresholds for risk tiers. +- Optional AI enrichment factor if enabled. + +Outputs: +- Overall score and risk tier. +- Category breakdowns. +- Top contributing red flags. +- Actionable recommendations for job seekers. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) + +#### Flowchart: Score Aggregation +```mermaid +flowchart TD +Start(["Start"]) --> LoadConfig["Load category weights and thresholds"] +LoadConfig --> CollectFlags["Collect red flags from detectors"] +CollectFlags --> Normalize["Normalize and validate flags"] +Normalize --> ComputeCategoryScores["Compute per-category scores"] +ComputeCategoryScores --> Aggregate["Aggregate into overall score"] +Aggregate --> Tier{"Exceeds threshold?"} +Tier --> |Yes| AssignHigh["Assign higher risk tier"] +Tier --> |No| AssignLow["Assign lower risk tier"] +AssignHigh --> Explain["Generate explanations and recommendations"] +AssignLow --> Explain +Explain --> End(["End"]) +``` + +**Diagram sources** +- [scoring.js](file://src/lib/scoring.js) + +### Orchestration Layer +The analyzer coordinates the full pipeline: +- Input parsing: Extracts relevant fields (title, description, requirements, benefits, compensation). +- Rule execution: Invokes detectors and collects red flags. +- AI assistance: Optionally calls AI services for deeper semantic checks using prompts. +- Report assembly: Combines flags, scores, and explanations into a user-friendly report. + +Integration points: +- Prompt templates for AI queries. +- AI service interface for asynchronous processing. +- UI components for input and output rendering. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +#### Sequence Diagram: Analysis Pipeline +```mermaid +sequenceDiagram +participant Analyzer as "analyze.js" +participant Rules as "redflags.js" +participant AI as "ai.js" +participant Prompt as "prompt.js" +participant Scorer as "scoring.js" +Analyzer->>Rules : "Evaluate text with detectors" +Rules-->>Analyzer : "Return red flags" +Analyzer->>Prompt : "Build AI prompt" +Analyzer->>AI : "Send prompt for enrichment" +AI-->>Analyzer : "Return AI insights" +Analyzer->>Scorer : "Aggregate flags + AI insights" +Scorer-->>Analyzer : "Return score and explanations" +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) + +### UI Integration +- ScanForm accepts job posting text and triggers analysis. +- ResultView renders red flags, severity, and recommendations. +- Settings allow users to adjust thresholds and category weights. + +User experience considerations: +- Clear labeling of severity levels. +- Concise explanations tied to specific parts of the posting. +- Actionable next steps (e.g., ask about salary range, clarify overtime policy). + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Dependency Analysis +The red flag system depends on modular libraries for detection, scoring, and optional AI enhancement. UI components depend on the orchestration layer to produce reports. + +```mermaid +graph TB +RF["redflags.js"] --> SC["scoring.js"] +RF --> AN["analyze.js"] +SC --> AN +AI["ai.js"] --> AN +PR["prompt.js"] --> AI +AN --> RV["ResultView.jsx"] +SF["ScanForm.jsx"] --> AN +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +## Performance Considerations +- Deterministic rule evaluation is lightweight and suitable for real-time scanning. +- AI-assisted checks should be optional and cached when possible to reduce latency. +- Preprocessing (normalization, tokenization) should minimize redundant operations. +- Batch processing can improve throughput when analyzing multiple postings. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- False positives due to generic phrases: Adjust thresholds or refine keyword lists. +- Missed detections: Expand regex patterns and add domain-specific terms. +- Inconsistent scores across runs: Ensure deterministic preprocessing and stable configuration. +- AI enrichment failures: Verify API availability and fallback to rule-only mode. + +Validation resources: +- Unit tests for detectors and scoring logic help confirm behavior changes. + +**Section sources** +- [redflags.test.js](file://src/lib/redflags.test.js) +- [scoring.test.js](file://src/lib/scoring.test.js) + +## Conclusion +The red flag detection system combines robust pattern matching with configurable severity and scoring to provide job seekers with clear, actionable insights. By tuning thresholds and weights, teams can adapt the system to local labor norms and user preferences while maintaining reliable risk assessments. Optional AI assistance enhances semantic understanding without compromising performance when used judiciously. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Reference +- Category weights: Control influence of each risk category on the overall score. +- Severity mapping: Defines how critical/high/medium/low flags translate into numerical weights. +- Thresholds: Determine risk tiers and pass/fail boundaries. +- Custom keywords and patterns: Extend detection coverage for industry-specific terms. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Scoring & Evaluation System.md b/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Scoring & Evaluation System.md new file mode 100644 index 0000000..64a74c0 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Scoring & Evaluation System.md @@ -0,0 +1,344 @@ +# Scoring & Evaluation System + + +**Referenced Files in This Document** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the scoring and evaluation system used by ApplyGuard PH to assess job applications and detect red flags in job postings. It covers: +- How application scores are computed from multiple criteria (experience match, skill alignment, company fit). +- The weighting system that combines sub-scores into a final score. +- Red flag detection mechanisms for issues such as salary transparency, company culture indicators, and employment terms. +- Thresholds, customization options, and how results are aggregated and persisted. + +The goal is to provide both technical depth and accessible explanations so that developers, product owners, and evaluators can understand and extend the system confidently. + +## Project Structure +The scoring and evaluation logic resides primarily under src/lib with supporting modules for AI prompts, statistics, and tests. Key files include: +- Scoring engine and aggregation +- Red flag detection rules +- Analysis orchestration and prompt management +- AI integration helpers +- Statistics utilities for result summaries + +```mermaid +graph TB +A["analyze.js"] --> B["scoring.js"] +A --> C["redflags.js"] +A --> D["prompt.js"] +A --> E["ai.js"] +B --> F["stats.js"] +C --> F +G["scoring.test.js"] --> B +H["redflags.test.js"] --> C +I["stats.test.js"] --> F +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +## Core Components +- Scoring Engine: Computes sub-scores per criterion, applies weights, normalizes, and aggregates into a final score. Provides thresholds and category labels. +- Red Flag Detector: Evaluates job posting text against rule-based heuristics and optional AI-assisted signals to identify potential issues across salary transparency, culture, and employment terms. +- Analysis Orchestrator: Coordinates data preparation, invokes scoring and red flag detection, and returns structured results. +- Prompt Manager: Builds prompts for AI features when needed. +- AI Helper: Interfaces with external AI services for enrichment or classification tasks. +- Stats Utilities: Aggregates and summarizes scores and flags for reporting. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [analyze.js](file://src/lib/analyze.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) + +## Architecture Overview +The evaluation pipeline processes an application and a target job posting through three main stages: +1. Data Preparation: Normalize inputs (resume/profile, job description, company info). +2. Scoring: Compute weighted sub-scores and produce a final score with categories. +3. Red Flag Detection: Identify risks and concerns; combine with scoring to form a comprehensive evaluation. + +```mermaid +sequenceDiagram +participant Client as "Client" +participant Analyzer as "analyze.js" +participant Scorer as "scoring.js" +participant Flags as "redflags.js" +participant Prompts as "prompt.js" +participant AI as "ai.js" +participant Stats as "stats.js" +Client->>Analyzer : "Evaluate(application, jobPosting)" +Analyzer->>Analyzer : "Prepare inputs" +Analyzer->>Scorer : "Compute sub-scores and weights" +Scorer-->>Analyzer : "Final score + breakdown" +Analyzer->>Flags : "Run red flag checks" +Flags-->>Analyzer : "Flags list with severity" +Analyzer->>Prompts : "Build prompts (optional)" +Prompts-->>AI : "Call AI service (optional)" +AI-->>Analyzer : "Enriched signals" +Analyzer->>Stats : "Aggregate results" +Stats-->>Client : "Evaluation report" +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) + +## Detailed Component Analysis + +### Scoring Engine +Responsibilities: +- Define criteria and their weights (e.g., experience match, skill alignment, company fit). +- Compute normalized sub-scores per criterion. +- Aggregate into a final score using weighted sum. +- Assign category labels based on thresholds. +- Provide customization hooks for different scenarios (e.g., role-specific weight adjustments). + +Key concepts: +- Sub-score calculation: Each criterion yields a value in a normalized range. +- Weighting system: Weights reflect importance; they may be configurable per scenario. +- Normalization: Ensures comparability across heterogeneous metrics. +- Thresholds: Map final scores to qualitative categories (e.g., strong, moderate, weak). + +Customization options: +- Role-specific weights: Adjust emphasis for certain roles or seniority levels. +- Criterion toggles: Enable/disable specific criteria depending on context. +- Threshold tuning: Adapt category boundaries for different markets or industries. + +```mermaid +flowchart TD +Start(["Start Scoring"]) --> Prepare["Normalize inputs
and extract features"] +Prepare --> Criteria["Compute sub-scores per criterion"] +Criteria --> Weights["Apply configured weights"] +Weights --> Aggregate["Weighted sum to final score"] +Aggregate --> Threshold{"Check thresholds"} +Threshold --> |Strong| LabelStrong["Assign 'Strong' category"] +Threshold --> |Moderate| LabelModerate["Assign 'Moderate' category"] +Threshold --> |Weak| LabelWeak["Assign 'Weak' category"] +LabelStrong --> End(["Return score + breakdown"]) +LabelModerate --> End +LabelWeak --> End +``` + +**Diagram sources** +- [scoring.js](file://src/lib/scoring.js) + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) + +### Red Flag Detection +Responsibilities: +- Detect potential issues in job postings across key areas: + - Salary transparency: Missing ranges, vague compensation language. + - Company culture indicators: Negative tone, excessive demands, lack of inclusivity cues. + - Employment terms: Ambiguous contracts, non-standard clauses, unclear expectations. +- Combine rule-based heuristics with optional AI-assisted signals for richer detection. +- Return flagged items with severity and rationale references. + +Detection approach: +- Rule-based checks: Keyword patterns, structural cues, and policy violations. +- Optional AI signals: Use prompts and AI helper to classify or enrich findings. +- Severity scoring: Assign risk levels to each flag for prioritization. + +```mermaid +flowchart TD +RFStart(["Start Red Flag Detection"]) --> Parse["Parse job posting text"] +Parse --> Rules["Apply rule-based heuristics"] +Rules --> AISignals["Optional AI-assisted analysis"] +AISignals --> Combine["Combine rules + AI signals"] +Combine --> Severity["Assign severity per flag"] +Severity --> Output(["Return flags with details"]) +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +### Analysis Orchestrator +Responsibilities: +- Coordinate input normalization and feature extraction. +- Invoke scoring and red flag detection. +- Integrate optional AI outputs. +- Produce a unified evaluation report including score, breakdown, and flags. + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant Analyzer as "analyze.js" +participant Scorer as "scoring.js" +participant Flags as "redflags.js" +participant Prompts as "prompt.js" +participant AI as "ai.js" +participant Stats as "stats.js" +Caller->>Analyzer : "Request evaluation" +Analyzer->>Scorer : "Compute score" +Scorer-->>Analyzer : "Score + breakdown" +Analyzer->>Flags : "Detect red flags" +Flags-->>Analyzer : "Flags list" +Analyzer->>Prompts : "Build prompts" +Prompts-->>AI : "Call AI" +AI-->>Analyzer : "Signals" +Analyzer->>Stats : "Aggregate" +Stats-->>Caller : "Report" +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [stats.js](file://src/lib/stats.js) + +### Metrics and Algorithms +- Experience Match: Quantifies overlap between candidate experience and job requirements. Uses normalized counts or similarity measures to derive a sub-score. +- Skill Alignment: Measures keyword and competency alignment between resume and job description. May incorporate semantic similarity via AI signals. +- Company Fit: Assesses cultural and organizational alignment based on company description and values extracted from the posting. + +Aggregation: +- Final Score = Sum(weight_i × normalized_sub_score_i) across all criteria i. +- Category assignment based on threshold bands defined in configuration. + +Thresholds and Customization: +- Thresholds are configurable to adapt to market conditions or role types. +- Weights can be tuned per scenario (e.g., prioritize skills for technical roles, emphasize culture for team-centric roles). + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) + +## Dependency Analysis +The evaluation system has clear separation of concerns: +- analyze.js orchestrates the flow and depends on scoring.js and redflags.js. +- scoring.js may depend on stats.js for aggregation and reporting. +- redflags.js may use prompt.js and ai.js for optional AI-assisted detection. +- Tests validate behavior for scoring, red flags, and stats. + +```mermaid +graph TB +Analyze["analyze.js"] --> Scoring["scoring.js"] +Analyze --> Flags["redflags.js"] +Scoring --> Stats["stats.js"] +Flags --> Prompts["prompt.js"] +Flags --> AI["ai.js"] +TestScoring["scoring.test.js"] --> Scoring +TestFlags["redflags.test.js"] --> Flags +TestStats["stats.test.js"] --> Stats +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +## Performance Considerations +- Prefer deterministic rule-based checks for speed-critical paths; reserve AI calls for optional enrichment. +- Cache repeated computations where possible (e.g., precomputed embeddings or normalized features). +- Batch operations when invoking AI services to reduce latency and cost. +- Keep threshold and weight configurations centralized for easy tuning without code changes. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Inconsistent scores across runs: Verify normalization steps and ensure stable inputs; check test coverage for edge cases. +- Missing red flags: Review rule definitions and consider enabling AI-assisted signals for ambiguous cases. +- Unexpected categories: Inspect threshold settings and adjust per market or role type. +- Slow evaluations: Reduce AI calls, enable caching, and profile bottlenecks in scoring and red flag detection. + +Validation resources: +- Unit tests for scoring, red flags, and stats help confirm expected behaviors and regression safety. + +**Section sources** +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +## Conclusion +The ApplyGuard PH scoring and evaluation system combines transparent, configurable algorithms with robust red flag detection to deliver actionable insights. By separating scoring, red flag detection, and orchestration, the system remains extensible and maintainable. Teams can tailor weights, thresholds, and criteria to diverse scenarios while leveraging optional AI assistance for richer signals. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Reference +- Weights: Per-criterion importance factors; adjustable per scenario. +- Thresholds: Score bands mapping to qualitative categories. +- Criterion toggles: Enable/disable criteria based on context. +- AI flags: Optional switches to include AI-assisted signals. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Scoring Algorithms.md b/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Scoring Algorithms.md new file mode 100644 index 0000000..09d3632 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Scoring & Evaluation System/Scoring Algorithms.md @@ -0,0 +1,483 @@ +# Scoring Algorithms + + +**Referenced Files in This Document** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction + +ApplyGuard PH implements a sophisticated multi-dimensional scoring system designed to evaluate job applications comprehensively. The scoring algorithms analyze various aspects of candidate-job fit including experience match, skill alignment, company culture compatibility, and specific job requirements. This document provides detailed technical documentation of the mathematical models, weighting systems, normalization techniques, and customization options available to users. + +The scoring system is designed to be fair, transparent, and customizable, allowing both automated evaluation and manual adjustment of scoring parameters to accommodate different organizational needs and preferences. + +## Project Structure + +The scoring functionality is primarily implemented in the `src/lib` directory, with supporting components in the UI layer. The main scoring logic resides in dedicated modules that handle calculation, validation, and result presentation. + +```mermaid +graph TB +subgraph "Scoring System Architecture" +A[Input Data] --> B[Data Preprocessing] +B --> C[Experience Match Engine] +B --> D[Skill Alignment Analyzer] +B --> E[Company Fit Calculator] +B --> F[Requirements Matcher] +C --> G[Weighted Score Aggregator] +D --> G +E --> G +F --> G +G --> H[Normalization Layer] +H --> I[Final Score Calculator] +I --> J[Threshold Evaluation] +J --> K[Result Output] +end +subgraph "UI Integration" +L[ScanForm] --> M[ResultView] +M --> N[Score Display] +end +K --> N +``` + +**Diagram sources** +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [analyze.js:1-150](file://src/lib/analyze.js#L1-L150) +- [ResultView.jsx:1-100](file://src/components/ResultView.jsx#L1-L100) + +## Core Components + +### Mathematical Models + +The scoring system employs several mathematical models to calculate comprehensive application scores: + +#### Weighted Sum Model +The primary scoring formula uses a weighted sum approach where each evaluation criterion contributes proportionally to its assigned weight: + +``` +Total Score = Σ(Criterion_i × Weight_i) / Σ(Weights) +``` + +Where: +- Criterion_i represents individual evaluation metrics (experience match, skills, etc.) +- Weight_i represents the importance factor for each criterion +- Normalization ensures all criteria are on comparable scales + +#### Threshold-Based Classification +Applications are classified into performance tiers using configurable thresholds: + +| Tier | Score Range | Classification | +|------|-------------|----------------| +| Excellent | 85-100 | Strong match | +| Good | 70-84 | Suitable candidate | +| Average | 50-69 | Needs improvement | +| Below Average | 30-49 | Significant gaps | +| Poor | 0-29 | Not recommended | + +#### Normalization Techniques +To ensure fair comparisons across diverse applications, the system applies multiple normalization techniques: + +1. **Min-Max Normalization**: Scales values to a 0-100 range +2. **Z-Score Standardization**: Accounts for statistical distribution +3. **Percentile Ranking**: Compares against applicant pool statistics + +### Scoring Criteria Breakdown + +#### Experience Match (Weight: 25%) +Evaluates years of relevant experience, industry background, and role-specific expertise: + +- **Years of Experience Factor**: Linear scaling from 0-100 based on required vs. actual experience +- **Industry Relevance**: Binary or categorical matching with bonus points for exact matches +- **Role Seniority Alignment**: Considers whether candidate's experience level matches position seniority + +#### Skill Alignment (Weight: 30%) +Analyzes technical and soft skills against job requirements: + +- **Technical Skills Match**: Keyword-based matching with confidence scoring +- **Soft Skills Assessment**: Behavioral indicators and communication patterns +- **Certification Verification**: Validates professional certifications and credentials + +#### Company Fit (Weight: 20%) +Assesses cultural compatibility and organizational alignment: + +- **Values Alignment**: Matches candidate values with company mission and culture +- **Work Style Compatibility**: Evaluates remote work preference, team collaboration style +- **Growth Mindset**: Assesses learning orientation and adaptability + +#### Job Requirements (Weight: 25%) +Focuses on specific job qualifications and must-have criteria: + +- **Education Requirements**: Degree verification and field relevance +- **Legal Eligibility**: Work authorization and visa status compliance +- **Availability & Logistics**: Location, schedule, and compensation expectations + +**Section sources** +- [scoring.js:1-300](file://src/lib/scoring.js#L1-L300) +- [scoring.test.js:1-200](file://src/lib/scoring.test.js#L1-L200) + +## Architecture Overview + +The scoring system follows a modular architecture with clear separation of concerns: + +```mermaid +sequenceDiagram +participant Client as "Client Application" +participant Scanner as "ScanForm Component" +participant Analyzer as "Analysis Engine" +participant Scorer as "Scoring Algorithm" +participant Validator as "Validation Layer" +participant Renderer as "ResultView Component" +Client->>Scanner : Submit Application Data +Scanner->>Analyzer : Process Raw Input +Analyzer->>Validator : Validate Data Integrity +Validator-->>Analyzer : Validation Results +Analyzer->>Scorer : Calculate Scores +Scorer->>Scorer : Apply Weights & Normalization +Scorer->>Scorer : Evaluate Thresholds +Scorer-->>Analyzer : Final Scores +Analyzer->>Renderer : Format Results +Renderer-->>Client : Display Score Report +Note over Scorer : Multi-stage scoring process
with feedback loops +``` + +**Diagram sources** +- [ScanForm.jsx:1-150](file://src/components/ScanForm.jsx#L1-L150) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [scoring.js:1-400](file://src/lib/scoring.js#L1-L400) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) + +## Detailed Component Analysis + +### Experience Match Engine + +The experience matching component evaluates candidate experience against job requirements using a multi-factor approach: + +```mermaid +flowchart TD +Start([Experience Data Input]) --> ParseExp["Parse Experience Data"] +ParseExp --> Categorize["Categorize Experience Types"] +Categorize --> CalculateYears["Calculate Years Factor"] +Categorize --> AssessRelevance["Assess Industry Relevance"] +Categorize --> EvaluateSeniority["Evaluate Role Seniority"] +CalculateYears --> NormalizeYears["Normalize to 0-100 Scale"] +AssessRelevance --> AssignRelevanceScore["Assign Relevance Score"] +EvaluateSeniority --> MatchSeniorityLevel["Match Seniority Level"] +NormalizeYears --> AggregateExp["Aggregate Experience Scores"] +AssignRelevanceScore --> AggregateExp +MatchSeniorityLevel --> AggregateExp +AggregateExp --> ApplyWeight["Apply 25% Weight"] +ApplyWeight --> ExperienceScore["Experience Match Score"] +``` + +**Diagram sources** +- [scoring.js:50-150](file://src/lib/scoring.js#L50-L150) + +#### Calculation Methodology + +The experience matching algorithm uses the following formula: + +``` +Experience Score = (Years Factor × 0.4) + (Relevance Score × 0.35) + (Seniority Match × 0.25) +``` + +Where: +- **Years Factor**: Calculated as min(actual_years / required_years, 1.0) × 100 +- **Relevance Score**: Based on industry keyword matching with confidence levels +- **Seniority Match**: Binary score (1.0 for exact match, 0.7 for adjacent levels, 0.3 for mismatch) + +### Skill Alignment Analyzer + +The skill analysis component performs comprehensive skill matching using natural language processing and pattern recognition: + +```mermaid +classDiagram +class SkillAnalyzer { ++string[] requiredSkills ++string[] candidateSkills ++number[] skillWeights ++calculateAlignment() number +-normalizeSkills() void +-matchKeywords() number +-assessProficiency() number +} +class SkillCategory { ++string category ++string[] skills ++number weight ++boolean isRequired +} +class ProficiencyLevel { ++string level ++number score ++string description +} +SkillAnalyzer --> SkillCategory : "uses" +SkillAnalyzer --> ProficiencyLevel : "calculates" +``` + +**Diagram sources** +- [scoring.js:150-250](file://src/lib/scoring.js#L150-L250) + +#### Skill Matching Algorithm + +The skill alignment scoring uses a weighted keyword matching approach: + +``` +Skill Score = Σ(Skill_i × Weight_i × Confidence_i) / Σ(Weights) +``` + +Where: +- **Skill_i**: Individual skill match score (0-100) +- **Weight_i**: Importance weight for each skill category +- **Confidence_i**: AI-assessed confidence in skill presence (0-1) + +### Company Fit Calculator + +The company fit assessment evaluates cultural and organizational compatibility through multiple dimensions: + +```mermaid +flowchart LR +Values["Values Alignment"] --> CulturalFit["Cultural Compatibility"] +WorkStyle["Work Style Match"] --> CulturalFit +GrowthMindset["Growth Orientation"] --> CulturalFit +Communication["Communication Style"] --> CulturalFit +CulturalFit --> CultureScore["Culture Score (0-100)"] +CultureScore --> ApplyWeight["Apply 20% Weight"] +ApplyWeight --> FinalFit["Company Fit Score"] +``` + +**Diagram sources** +- [scoring.js:250-350](file://src/lib/scoring.js#L250-L350) + +### Requirements Matcher + +The requirements matching component focuses on hard qualifications and legal eligibility: + +#### Education Verification +- Degree type and field relevance assessment +- Institution accreditation validation +- GPA threshold checking (if applicable) + +#### Legal Compliance +- Work authorization status verification +- Visa sponsorship requirements +- Background check clearance + +#### Logistical Compatibility +- Geographic location matching +- Remote work capability assessment +- Schedule availability confirmation + +**Section sources** +- [scoring.js:1-400](file://src/lib/scoring.js#L1-L400) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) + +## Dependency Analysis + +The scoring system has well-defined dependencies and clear separation between calculation logic and presentation layers: + +```mermaid +graph TD +subgraph "Core Dependencies" +A[scoring.js] --> B[analyze.js] +A --> C[ai.js] +B --> D[prompt.js] +C --> E[external APIs] +end +subgraph "UI Dependencies" +F[ResultView.jsx] --> A +G[ScanForm.jsx] --> B +H[Settings.jsx] --> A +end +subgraph "External Services" +I[AI Processing] --> C +J[Validation Services] --> B +K[Storage Backend] --> F +end +A --> F +B --> G +``` + +**Diagram sources** +- [scoring.js:1-50](file://src/lib/scoring.js#L1-L50) +- [analyze.js:1-50](file://src/lib/analyze.js#L1-L50) +- [ResultView.jsx:1-50](file://src/components/ResultView.jsx#L1-L50) + +### Coupling and Cohesion Analysis + +The scoring system demonstrates high cohesion within modules and low coupling between components: + +- **High Cohesion**: Each module focuses on specific scoring aspects +- **Low Coupling**: Clear interfaces between calculation and presentation layers +- **Modular Design**: Easy to extend with new scoring criteria +- **Testable Architecture**: Unit tests cover core calculation logic + +**Section sources** +- [scoring.js:1-100](file://src/lib/scoring.js#L1-L100) +- [scoring.test.js:1-100](file://src/lib/scoring.test.js#L1-L100) + +## Performance Considerations + +### Computational Efficiency + +The scoring algorithms are optimized for real-time processing: + +- **Lazy Loading**: Heavy calculations only performed when needed +- **Caching**: Frequently accessed data cached to reduce computation time +- **Batch Processing**: Multiple applications scored simultaneously when possible +- **Progressive Enhancement**: Basic scores calculated first, detailed analysis follows + +### Memory Management + +Memory usage is controlled through: + +- **Stream Processing**: Large datasets processed in chunks +- **Garbage Collection**: Temporary objects cleaned up promptly +- **Resource Pooling**: Shared resources reused across calculations + +### Scalability + +The system supports horizontal scaling through: + +- **Stateless Calculations**: No persistent state between requests +- **Distributed Processing**: Load balancing across multiple instances +- **Database Optimization**: Indexed queries for fast data retrieval + +## Troubleshooting Guide + +### Common Scoring Issues + +#### Inconsistent Scores Across Runs +**Symptoms**: Same application produces different scores on repeated evaluations +**Causes**: +- Non-deterministic AI processing +- Time-dependent factors in calculations +- Random seed variations in sampling + +**Solutions**: +- Set fixed random seeds for reproducibility +- Cache AI responses for identical inputs +- Implement deterministic fallback algorithms + +#### Score Distribution Problems +**Symptoms**: All applications cluster around similar score ranges +**Causes**: +- Insufficient differentiation in weighting +- Overly aggressive normalization +- Limited input data quality + +**Solutions**: +- Adjust weight distributions for better discrimination +- Implement adaptive normalization based on dataset characteristics +- Enhance data collection to provide more granular information + +#### Performance Degradation +**Symptoms**: Slow scoring times, especially with large applicant pools +**Causes**: +- Excessive AI API calls +- Inefficient data processing +- Memory leaks in long-running processes + +**Solutions**: +- Implement request batching and caching +- Optimize data structures for faster access +- Monitor memory usage and implement cleanup routines + +### Debugging Tools + +The system includes comprehensive debugging capabilities: + +- **Score Breakdown**: Detailed view of individual criterion contributions +- **Calculation Logs**: Step-by-step scoring process documentation +- **Performance Metrics**: Timing and resource usage statistics +- **Validation Reports**: Data quality and completeness assessments + +**Section sources** +- [scoring.test.js:100-300](file://src/lib/scoring.test.js#L100-L300) +- [analyze.js:150-250](file://src/lib/analyze.js#L150-L250) + +## Conclusion + +The ApplyGuard PH scoring system provides a robust, flexible, and transparent framework for evaluating job applications. Through its multi-dimensional approach combining experience matching, skill alignment, company fit assessment, and requirements verification, the system delivers comprehensive candidate evaluation while maintaining fairness and accuracy. + +Key strengths include: + +- **Mathematical Rigor**: Well-defined formulas with proper normalization +- **Customizability**: Configurable weights and thresholds for different use cases +- **Transparency**: Detailed breakdowns of score contributions +- **Scalability**: Efficient processing suitable for large applicant volumes +- **Extensibility**: Modular design allows easy addition of new evaluation criteria + +The system successfully balances automation with human oversight, providing organizations with powerful tools for talent acquisition while maintaining the flexibility to accommodate unique organizational needs and preferences. + +## Appendices + +### Customization Guide + +#### Adjusting Scoring Weights +Users can customize the relative importance of different scoring criteria through the settings interface: + +1. Navigate to Settings → Scoring Configuration +2. Modify weight percentages for each criterion +3. Ensure total weights equal 100% +4. Save configuration and test with sample applications + +#### Configuring Thresholds +Performance tier thresholds can be adjusted based on organizational standards: + +1. Access Advanced Settings → Threshold Configuration +2. Modify score boundaries for each performance tier +3. Configure automatic actions based on score ranges +4. Test threshold effectiveness with historical data + +#### Adding Custom Criteria +Organizations can extend the scoring system with custom evaluation criteria: + +1. Define new criterion in Settings → Custom Criteria +2. Specify calculation method and data sources +3. Assign appropriate weight percentage +4. Validate with test applications before deployment + +### Mathematical Reference + +#### Normalization Formulas + +**Min-Max Normalization**: +``` +x_normalized = (x - x_min) / (x_max - x_min) × 100 +``` + +**Z-Score Standardization**: +``` +z = (x - μ) / σ +``` + +**Weighted Average**: +``` +score = Σ(x_i × w_i) / Σ(w_i) +``` + +#### Statistical Measures + +The system calculates additional statistical measures for enhanced insights: + +- **Percentile Rank**: Position within applicant pool +- **Standard Deviation**: Score variability assessment +- **Correlation Analysis**: Relationship between criteria +- **Trend Analysis**: Historical performance tracking \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Business Logic Layer/Statistics & Analytics Engine.md b/.qoder/repowiki/en/content/Business Logic Layer/Statistics & Analytics Engine.md new file mode 100644 index 0000000..c010fc0 --- /dev/null +++ b/.qoder/repowiki/en/content/Business Logic Layer/Statistics & Analytics Engine.md @@ -0,0 +1,398 @@ +# Statistics & Analytics Engine + + +**Referenced Files in This Document** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the statistics and analytics engine in ApplyGuard PH, focusing on how job search metrics are calculated, aggregated, analyzed over time, and presented to users. It covers: +- Calculation methods for key metrics (success rates, time-to-response, conversion rates) +- Data aggregation algorithms and trend analysis +- Reporting generation and export formats +- Visualization data structures and dashboard integration points +- Examples of common analytics queries and custom metric definitions + +The goal is to make the analytics system understandable for both technical and non-technical readers while providing precise references to implementation files. + +## Project Structure +The analytics functionality is implemented primarily in client-side JavaScript modules under src/lib and consumed by UI components under src/components. Key areas include: +- Core statistical computations and aggregations +- Time-series and trend utilities +- Export helpers for CSV and cloud sync +- Dashboard integration via store and component state + +```mermaid +graph TB +subgraph "Analytics Library" +stats["stats.js"] +csv["csv.js"] +cloud["cloud.js"] +sync["sync.js"] +followups["followups.js"] +scoring["scoring.js"] +analyze["analyze.js"] +end +subgraph "UI Components" +tracker["Tracker.jsx"] +result["ResultView.jsx"] +end +subgraph "State & Data" +store["store.jsx"] +supabase["supabase.js"] +end +tracker --> stats +result --> stats +tracker --> followups +result --> scoring +tracker --> csv +tracker --> cloud +cloud --> sync +store --> supabase +stats --> csv +stats --> cloud +``` + +**Diagram sources** +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) + +## Core Components +- Statistical computation module: Provides functions for success rate, conversion rate, time-to-response, and other core metrics. +- Aggregation and trend utilities: Group records by categories or companies, compute rolling windows, and derive trends. +- Export and sync helpers: Generate CSV exports and integrate with cloud storage for sharing or backup. +- Follow-ups and scoring integrations: Enrich analytics with application status transitions and scoring insights. +- UI integration: Tracker and ResultView consume analytics outputs to render dashboards and detailed views. + +Key responsibilities: +- Normalize input datasets into a consistent schema for calculations +- Compute per-period and cumulative metrics +- Produce visualization-ready structures (time series, category/company breakdowns) +- Provide exportable reports and shareable snapshots + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +The analytics pipeline reads raw job applications from local storage or synced cloud, normalizes them, computes metrics, aggregates across dimensions, and renders results in the UI. Exports can be generated as CSV or shared via cloud. + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx / ResultView.jsx" +participant Store as "store.jsx" +participant Stats as "stats.js" +participant Followups as "followups.js" +participant Scoring as "scoring.js" +participant CSV as "csv.js" +participant Cloud as "cloud.js" +participant Sync as "sync.js" +participant Supabase as "supabase.js" +UI->>Store : Request analytics data +Store-->>UI : Raw applications + metadata +UI->>Stats : Compute metrics (success, conversion, TTR) +Stats->>Followups : Resolve status transitions +Stats->>Scoring : Incorporate score-based filters +Stats-->>UI : Aggregated metrics + time series +UI->>CSV : Generate report export +UI->>Cloud : Save/share snapshot +Cloud->>Sync : Persist to cloud +Sync->>Supabase : Sync with backend +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Statistical Computation Module +Responsibilities: +- Success rate calculation: ratio of successful outcomes to total attempts within a selected period or overall. +- Conversion rate calculation: progression through funnel stages (e.g., applied → interview → offer). +- Time-to-response (TTR): elapsed time between application submission and first meaningful response. +- Category/company comparative analytics: group-by metrics for cross-sectional comparisons. +- Trend analysis: rolling averages, moving windows, and growth indicators. + +Common formulas: +- Success Rate = Successful Outcomes / Total Attempts +- Conversion Rate = Stage N Completions / Stage N-1 Entrances +- Time-to-Response = Timestamp(First Response) - Timestamp(Application Date) +- Comparative Metric Delta = Metric(Category A) - Metric(Category B) + +Visualization data structures: +- TimeSeriesPoint: { date, value } +- BreakdownEntry: { label, count, rate } +- ComparisonSet: { category, company, metrics } + +Export formats: +- CSV rows with headers for each metric dimension +- JSON snapshots for cloud sharing + +Integration points: +- Consumed by Tracker.jsx and ResultView.jsx for dashboard rendering +- Uses followups.js for status transitions and scoring.js for score-based filtering + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +#### Class-like Structure of Analytics Outputs +```mermaid +classDiagram +class TimeSeriesPoint { ++date string ++value number +} +class BreakdownEntry { ++label string ++count number ++rate number +} +class ComparisonSet { ++category string ++company string ++metrics object +} +class AnalyticsReport { ++summary object ++trends TimeSeriesPoint[] ++breakdown BreakdownEntry[] ++comparisons ComparisonSet[] +} +AnalyticsReport --> TimeSeriesPoint : "contains" +AnalyticsReport --> BreakdownEntry : "contains" +AnalyticsReport --> ComparisonSet : "contains" +``` + +**Diagram sources** +- [stats.js](file://src/lib/stats.js) + +### Aggregation and Trend Analysis +Aggregation algorithm highlights: +- Grouping by date ranges (daily, weekly, monthly) +- Rolling window computations for smoothing +- Cumulative sums and running rates +- Dimensional pivots by category and company + +Trend analysis methods: +- Moving average over configurable windows +- Growth rate computed as percentage change between periods +- Anomaly detection flags based on deviation thresholds + +Data flow: +- Input normalized applications → grouped by period/dimension → computed metrics → smoothed trends → output structures for visualization + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) + +### Export and Reporting Generation +Export capabilities: +- CSV generation with standardized headers +- JSON snapshot creation for cloud sharing +- Report templates for summary, trends, and breakdowns + +Reporting process: +- Aggregate metrics → format into rows/columns → write to CSV or JSON → persist via cloud if requested + +Integration points: +- csv.js for formatting +- cloud.js for persistence +- sync.js for backend synchronization + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +### Dashboard Integration +Components: +- Tracker.jsx: Displays overview metrics, timelines, and quick actions +- ResultView.jsx: Presents detailed analytics for specific applications or cohorts + +Data consumption: +- Reads from store.jsx which coordinates local and cloud data +- Calls stats.js to compute metrics on demand or cached results +- Renders charts and tables using visualization-ready structures + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Follow-ups and Scoring Integrations +Follow-ups: +- Status transitions drive conversion rate and funnel analytics +- Timeline alignment ensures accurate TTR calculations + +Scoring: +- Score-based filters enable cohort analytics (e.g., high-score vs low-score applicants) +- Correlation between scores and outcomes enriches comparative analytics + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) + +## Dependency Analysis +The analytics engine depends on several modules for data normalization, status tracking, scoring, export, and cloud sync. The following diagram shows direct dependencies among core files. + +```mermaid +graph LR +stats["stats.js"] --> followups["followups.js"] +stats --> scoring["scoring.js"] +stats --> csv["csv.js"] +stats --> cloud["cloud.js"] +cloud --> sync["sync.js"] +sync --> supabase["supabase.js"] +tracker["Tracker.jsx"] --> stats +result["ResultView.jsx"] --> stats +store["store.jsx"] --> supabase +``` + +**Diagram sources** +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) + +## Performance Considerations +- Prefer batched computations: aggregate once and reuse results across components to avoid redundant recalculations. +- Use memoization for expensive operations like rolling windows and multi-dimensional pivots. +- Limit time range granularity when generating large exports; provide pagination or sampling options. +- Cache visualization-ready structures in store.jsx to reduce re-renders. +- Defer heavy exports until user explicitly triggers them; consider background tasks for large datasets. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing timestamps: Ensure application dates and response dates are present; otherwise, exclude records from TTR calculations. +- Inconsistent statuses: Validate status transitions via followups.js; normalize ambiguous states before computing conversion rates. +- Empty exports: Verify CSV headers and row formatting; confirm that at least one record matches the selected filters. +- Sync failures: Check cloud.js and sync.js error paths; retry with backoff and log errors for diagnosis. + +Operational checks: +- Confirm store.jsx has up-to-date data before invoking analytics. +- Validate that stats.js receives normalized inputs matching expected schemas. +- Inspect test suites in stats.test.js for edge cases and assertions. + +**Section sources** +- [stats.test.js](file://src/lib/stats.test.js) +- [followups.js](file://src/lib/followups.js) +- [csv.js](file://src/lib/csv.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [store.jsx](file://src/store.jsx) + +## Conclusion +The ApplyGuard PH analytics engine combines robust statistical computations, flexible aggregation, and clear export mechanisms to deliver actionable insights into job search performance. By integrating follow-up tracking and scoring, it supports nuanced analyses across categories and companies. The modular design enables easy extension for new metrics and visualizations while maintaining clarity and performance. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Common Analytics Queries +- Success rate by category: Filter applications by category, compute successes divided by total attempts. +- Conversion rate by company: Track stage transitions per company and calculate completion ratios. +- Average time-to-response by month: Group responses by month and compute mean TTR. +- Trend of interviews over last 12 weeks: Build a weekly time series of interview counts and apply a moving average. + +### Custom Metric Definitions +- Weighted success score: Combine outcome types with weights (e.g., offer > interview > callback). +- Funnel drop-off rate: Percentage decrease between consecutive stages. +- Cohort retention: Proportion of applicants who continue applying after a milestone. + +### Visualization Data Structures +- TimeSeriesPoint: { date, value } +- BreakdownEntry: { label, count, rate } +- ComparisonSet: { category, company, metrics } + +These structures are produced by the analytics module and consumed by Tracker.jsx and ResultView.jsx for rendering charts and tables. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/AI Assistant & Coaching.md b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/AI Assistant & Coaching.md new file mode 100644 index 0000000..b5160f6 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/AI Assistant & Coaching.md @@ -0,0 +1,442 @@ +# AI Assistant & Coaching + + +**Referenced Files in This Document** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [tone.js](file://src/lib/tone.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The AI Assistant & Coaching system is a comprehensive interview preparation platform that leverages artificial intelligence to provide personalized coaching, contextual feedback, and adaptive learning experiences. The system analyzes user inputs during mock interviews, provides constructive feedback, suggests improvements, and maintains conversation context throughout sessions to deliver an immersive and effective interview preparation experience. + +## Project Structure + +The AI coaching system follows a modular architecture with clear separation between frontend components, business logic, and backend services: + +```mermaid +graph TB +subgraph "Frontend Layer" +UI[AiAssistant.jsx] +Interview[MockInterviewPage.jsx] +Results[ResultView.jsx] +end +subgraph "Business Logic Layer" +AI[ai.js] +Prompt[prompt.js] +Analyze[analyze.js] +Score[scoring.js] +Tone[tone.js] +end +subgraph "Backend Services" +Proxy[ai-proxy/index.ts] +Prompts[prompts.ts] +end +subgraph "External APIs" +LLM[Large Language Model API] +Storage[(User Data Storage)] +end +UI --> AI +Interview --> UI +Results --> Analyze +AI --> Prompt +AI --> Analyze +AI --> Score +AI --> Tone +AI --> Proxy +Proxy --> LLM +Proxy --> Prompts +AI --> Storage +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +## Core Components + +### Conversational Interface (AiAssistant.jsx) +The main conversational interface component handles real-time chat interactions, manages conversation state, and coordinates with the AI processing pipeline. It provides the primary user interaction point for interview preparation sessions. + +### AI Processing Engine (ai.js) +The core AI processing engine orchestrates the entire AI workflow, including prompt generation, response analysis, scoring algorithms, and tone detection. It serves as the central coordinator for all AI-related functionality. + +### Prompt Engineering System (prompt.js) +This module handles dynamic prompt construction, context management, and prompt optimization strategies. It ensures prompts are tailored to individual users and maintain conversation continuity. + +### Analysis Framework (analyze.js) +The analysis framework processes AI responses, extracts key insights, identifies areas for improvement, and generates structured feedback for users. + +### Scoring System (scoring.js) +The scoring system evaluates user performance across multiple dimensions, providing quantitative metrics and qualitative assessments for interview readiness. + +### Tone Detection (tone.js) +Tone detection analyzes communication style, emotional intelligence, and professional demeanor to provide nuanced feedback on interpersonal skills. + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [tone.js](file://src/lib/tone.js) + +## Architecture Overview + +The AI coaching system implements a sophisticated multi-layered architecture designed for scalability, reliability, and performance: + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "AiAssistant.jsx" +participant AI as "ai.js" +participant Prompt as "prompt.js" +participant Proxy as "ai-proxy/index.ts" +participant LLM as "LLM API" +participant Storage as "Storage" +User->>UI : Submit interview answer +UI->>AI : Process user input +AI->>Prompt : Generate contextual prompt +Prompt-->>AI : Optimized prompt +AI->>Proxy : Send request with context +Proxy->>LLM : Forward to language model +LLM-->>Proxy : AI response +Proxy-->>AI : Structured response +AI->>AI : Analyze response quality +AI->>AI : Apply scoring algorithms +AI->>AI : Detect communication tone +AI->>Storage : Save conversation context +AI-->>UI : Enhanced feedback +UI-->>User : Personalized coaching response +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Detailed Component Analysis + +### Conversational Interface Architecture + +The AiAssistant component implements a stateful conversation manager that maintains context across multiple interactions: + +```mermaid +classDiagram +class AiAssistant { ++conversationHistory Array ++userContext Object ++sessionState Object ++sendMessage(message) Promise ++updateContext(data) void ++clearSession() void ++getConversationSummary() Object +} +class ConversationManager { ++contextWindow Number ++maxHistory Size ++saveToStorage() void ++loadFromStorage() void ++mergeContexts(old, new) Object +} +class FeedbackEngine { ++analyzeResponse(response) Object ++generateSuggestions(feedback) Array ++calculateImprovementScore(current, previous) Number +} +AiAssistant --> ConversationManager : "uses" +AiAssistant --> FeedbackEngine : "integrates" +ConversationManager --> FeedbackEngine : "provides context" +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +### AI Processing Pipeline + +The AI processing pipeline implements a sophisticated multi-stage analysis system: + +```mermaid +flowchart TD +Start([User Input Received]) --> Validate["Validate Input Format"] +Validate --> Valid{"Input Valid?"} +Valid --> |No| ErrorHandle["Error Handling & Fallback"] +Valid --> |Yes| ContextBuild["Build Context Window"] +ContextBuild --> PromptGen["Generate Dynamic Prompt"] +PromptGen --> APICall["Call AI Service"] +APICall --> ResponseParse["Parse AI Response"] +ResponseParse --> QualityCheck["Quality Assessment"] +QualityCheck --> GoodQuality{"Quality Sufficient?"} +GoodQuality --> |No| RetryLogic["Retry with Enhanced Prompt"] +GoodQuality --> |Yes| Analysis["Multi-dimensional Analysis"] +Analysis --> Scoring["Apply Scoring Algorithms"] +Scoring --> ToneAnalysis["Analyze Communication Tone"] +ToneAnalysis --> FeedbackGen["Generate Personalized Feedback"] +FeedbackGen --> ContextUpdate["Update Conversation Context"] +ContextUpdate --> StoreData["Store Session Data"] +StoreData --> ReturnResponse["Return Enhanced Response"] +ErrorHandle --> FallbackResponse["Provide Fallback Response"] +FallbackResponse --> ReturnResponse +RetryLogic --> APICall +``` + +**Diagram sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [analyze.js](file://src/lib/analyze.js) + +### Backend Proxy Architecture + +The Supabase function proxy provides secure API access and request routing: + +```mermaid +sequenceDiagram +participant Client as "Frontend ai.js" +participant Proxy as "ai-proxy/index.ts" +participant Auth as "Authentication" +participant RateLimit as "Rate Limiter" +participant LLM as "Language Model API" +participant Cache as "Response Cache" +Client->>Proxy : HTTP Request with payload +Proxy->>Auth : Validate authentication +Auth-->>Proxy : Auth token verified +Proxy->>RateLimit : Check rate limits +RateLimit-->>Proxy : Allow/Deny request +Proxy->>Cache : Check cached response +Cache-->>Proxy : Cached data or miss +alt Cache Hit +Proxy-->>Client : Return cached response +else Cache Miss +Proxy->>LLM : Forward processed request +LLM-->>Proxy : AI response +Proxy->>Cache : Store response +Proxy-->>Client : Return fresh response +end +``` + +**Diagram sources** +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +### Prompt Engineering System + +The prompt engineering system implements dynamic prompt construction with context awareness: + +```mermaid +classDiagram +class PromptEngine { ++basePrompts Map ++contextualRules Array ++userProfiles Object ++generatePrompt(userInput, context) String ++optimizeForClarity(prompt) String ++addPersonalization(prompt, profile) String +} +class ContextManager { ++conversationHistory Array ++userPreferences Object ++learningProgress Object ++extractKeyPoints(text) Array ++buildContextWindow(messages) Object +} +class PromptOptimizer { ++temperature Float ++maxTokens Number ++formattingRules Array ++enhanceStructure(prompt) String ++addExamples(prompt, examples) String +} +PromptEngine --> ContextManager : "uses" +PromptEngine --> PromptOptimizer : "optimizes" +ContextManager --> PromptOptimizer : "provides context" +``` + +**Diagram sources** +- [prompt.js](file://src/lib/prompt.js) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + +### Analysis and Scoring Framework + +The analysis framework provides comprehensive evaluation capabilities: + +```mermaid +flowchart LR +subgraph "Input Processing" +A[Raw Response] --> B[Text Preprocessing] +B --> C[Entity Extraction] +end +subgraph "Content Analysis" +C --> D[Relevance Scoring] +C --> E[Completeness Check] +C --> F[Technical Accuracy] +end +subgraph "Communication Analysis" +C --> G[Tone Detection] +C --> H[Clarity Assessment] +C --> I[Professionalism Rating] +end +subgraph "Feedback Generation" +D --> J[Composite Score] +E --> J +F --> J +G --> K[Communication Score] +H --> K +I --> K +J --> L[Overall Assessment] +K --> L +end +subgraph "Output Formatting" +L --> M[Structured Feedback] +L --> N[Improvement Suggestions] +L --> O[Action Items] +end +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [tone.js](file://src/lib/tone.js) + +## Dependency Analysis + +The AI coaching system exhibits a well-structured dependency hierarchy with clear separation of concerns: + +```mermaid +graph TD +subgraph "Core Dependencies" +React[React Framework] +Supabase[Supabase Functions] +LLM[Language Model API] +end +subgraph "Internal Modules" +AI[ai.js] +Prompt[prompt.js] +Analyze[analyze.js] +Score[scoring.js] +Tone[tone.js] +end +subgraph "UI Components" +Assistant[AiAssistant.jsx] +Interview[MockInterviewPage.jsx] +Results[ResultView.jsx] +end +React --> Assistant +React --> Interview +React --> Results +Assistant --> AI +Interview --> Assistant +Results --> Analyse +AI --> Prompt +AI --> Analyze +AI --> Score +AI --> Tone +AI --> Supabase +Supabase --> LLM +``` + +**Diagram sources** +- [ai.js](file://src/lib/ai.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Performance Considerations + +The AI coaching system implements several performance optimization strategies: + +### Caching Strategies +- **Response Caching**: Intelligent caching of frequently accessed prompts and responses +- **Context Window Optimization**: Efficient management of conversation history to minimize memory usage +- **Lazy Loading**: Progressive loading of analysis results and detailed feedback + +### Concurrency Management +- **Request Queuing**: Sequential processing of AI requests to prevent API overload +- **Connection Pooling**: Reuse of database connections for improved throughput +- **Batch Processing**: Grouping related operations to reduce network overhead + +### Memory Management +- **Stream Processing**: Real-time processing of large text inputs without full memory allocation +- **Garbage Collection Optimization**: Proper cleanup of conversation contexts and temporary objects +- **Resource Cleanup**: Automatic disposal of unused resources and event listeners + +### Network Optimization +- **Compression**: Request and response compression for reduced bandwidth usage +- **Timeout Handling**: Configurable timeouts with exponential backoff retry logic +- **Error Recovery**: Graceful degradation when external services are unavailable + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### AI Service Connectivity Problems +- **Symptoms**: Timeout errors, connection refused messages +- **Causes**: Network connectivity issues, API service downtime, authentication failures +- **Solutions**: Implement retry logic, provide fallback responses, monitor service health + +#### Context Loss During Conversations +- **Symptoms**: AI loses track of conversation topics, forgets previous interactions +- **Causes**: Context window overflow, session expiration, storage failures +- **Solutions**: Implement context summarization, automatic session recovery, local storage backup + +#### Performance Degradation +- **Symptoms**: Slow response times, high memory usage, UI freezing +- **Causes**: Large conversation histories, inefficient algorithms, memory leaks +- **Solutions**: Optimize context windows, implement lazy loading, add performance monitoring + +#### Inconsistent Feedback Quality +- **Symptoms**: Varying quality of AI responses, irrelevant suggestions +- **Causes**: Poor prompt engineering, insufficient context, model limitations +- **Solutions**: Enhance prompt templates, improve context building, implement quality checks + +### Monitoring and Diagnostics + +#### Logging Strategy +- **Structured Logging**: JSON-formatted logs with consistent schema +- **Performance Metrics**: Response times, error rates, resource utilization +- **User Analytics**: Interaction patterns, feature usage, satisfaction metrics + +#### Error Tracking +- **Exception Handling**: Comprehensive try-catch blocks with meaningful error messages +- **Stack Traces**: Detailed error information for debugging +- **User-Friendly Messages**: Clear error descriptions with suggested actions + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Conclusion + +The AI Assistant & Coaching system represents a sophisticated approach to interview preparation through intelligent automation and personalized feedback. The modular architecture ensures maintainability and scalability, while the comprehensive analysis framework provides actionable insights for continuous improvement. + +Key strengths include the context-aware conversation management, multi-dimensional analysis capabilities, and robust error handling mechanisms. The system successfully balances advanced AI capabilities with practical usability, making it accessible to users at various skill levels. + +Future enhancements could include expanded language model integration, more sophisticated personality adaptation, and enhanced analytics for tracking long-term progress. The current implementation provides a solid foundation for these future developments while delivering immediate value to users seeking to improve their interview performance. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/AI Interview Preparation.md b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/AI Interview Preparation.md new file mode 100644 index 0000000..0e5e468 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/AI Interview Preparation.md @@ -0,0 +1,417 @@ +# AI Interview Preparation + + +**Referenced Files in This Document** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [prompt.js](file://src/lib/prompt.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [index.html](file://index.html) +- [package.json](file://package.json) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes an AI-powered interview preparation system that helps candidates practice with a mock interview interface, generate relevant questions from job descriptions and resumes, evaluate responses, and analyze tone for coaching insights. It explains how the AI assistant provides personalized guidance, integrates with resume analysis and industry-specific question banks, and tracks performance over time. The guide includes examples of interview sessions, customization options, and tips to maximize coaching effectiveness. + +## Project Structure +The application is a modern web app built with React and Vite. Key areas include: +- UI components for the mock interview flow, AI assistant chat, and results visualization +- Libraries for AI orchestration, prompt construction, response analysis, scoring, and tone evaluation +- Data persistence via Supabase client utilities +- App shell and routing entry points + +```mermaid +graph TB +A["index.html"] --> B["App.jsx"] +B --> C["MockInterviewPage.jsx"] +B --> D["AiAssistant.jsx"] +B --> E["ResultView.jsx"] +C --> F["ai.js"] +C --> G["prompt.js"] +C --> H["analyze.js"] +C --> I["tone.js"] +C --> J["scoring.js"] +C --> K["supabase.js"] +D --> F +D --> G +E --> J +E --> I +E --> H +``` + +**Diagram sources** +- [index.html:1-200](file://index.html#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +**Section sources** +- [index.html:1-200](file://index.html#L1-L200) +- [package.json:1-200](file://package.json#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) + +## Core Components +- MockInterviewPage: Orchestrates the end-to-end mock interview session, including question generation, candidate input capture, AI-driven follow-ups, and result compilation. +- AiAssistant: Provides conversational coaching, contextual hints, and explanations based on the current question and candidate’s answer. +- ResultView: Displays structured feedback, scores, strengths, gaps, and tone insights after each session or per question. +- ai.js: Central AI integration layer for calling language models, handling retries, streaming (if applicable), and error propagation. +- prompt.js: Builds prompts tailored to role, experience level, and industry; supports templates and dynamic variables. +- analyze.js: Parses and structures candidate answers into key dimensions (e.g., STAR structure, relevance, completeness). +- tone.js: Evaluates communication style, confidence, clarity, and empathy signals. +- scoring.js: Aggregates metrics across dimensions into final scores and actionable recommendations. +- supabase.js: Client configuration and helpers for storing sessions, progress, and analytics. + +**Section sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +## Architecture Overview +The system follows a layered architecture: +- Presentation Layer: React components for interview flow, coaching chat, and results. +- Orchestration Layer: Session state management and coordination between AI calls, analysis, and scoring. +- AI Integration Layer: Prompt building and model invocation. +- Analytics Layer: Response analysis, tone evaluation, and scoring aggregation. +- Persistence Layer: Supabase-backed storage for sessions and progress tracking. + +```mermaid +sequenceDiagram +participant U as "User" +participant MIP as "MockInterviewPage" +participant AI as "ai.js" +participant PR as "prompt.js" +participant AN as "analyze.js" +participant TO as "tone.js" +participant SC as "scoring.js" +participant SB as "supabase.js" +U->>MIP : "Start Mock Interview" +MIP->>PR : "Build prompt (role, JD, resume)" +PR-->>MIP : "Prompt payload" +MIP->>AI : "Request question(s)" +AI-->>MIP : "Generated question(s)" +U->>MIP : "Submit answer" +MIP->>AN : "Analyze answer structure/relevance" +AN-->>MIP : "Analysis" +MIP->>TO : "Evaluate tone" +TO-->>MIP : "Tone insights" +MIP->>SC : "Compute scores" +SC-->>MIP : "Scores + recommendations" +MIP->>SB : "Persist session" +SB-->>MIP : "Saved" +MIP-->>U : "Show results and coaching" +``` + +**Diagram sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +## Detailed Component Analysis + +### MockInterviewPage +Responsibilities: +- Initialize session parameters (role, seniority, industry, focus areas) +- Generate questions using AI with context from job description and resume +- Capture and validate candidate responses +- Trigger analysis, tone evaluation, and scoring +- Persist session data and render results + +Key interactions: +- Uses prompt.js to construct role-aware prompts +- Calls ai.js to request questions and optional follow-ups +- Integrates analyze.js and tone.js for deeper insights +- Persists via supabase.js + +Customization options: +- Role and seniority filters +- Industry-specific question bank selection +- Difficulty and depth controls +- Focus on behavioral vs technical vs situational questions + +Example session flow: +- Candidate selects “Senior Product Manager” and uploads a resume +- System generates 5 targeted questions +- Candidate answers each; AI provides follow-up probes +- Results show dimension scores, tone insights, and coaching tips + +**Section sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +### AiAssistant +Responsibilities: +- Provide real-time coaching hints and explanations +- Summarize best practices for answering specific questions +- Offer alternative phrasing and structure suggestions +- Maintain conversation context within the session + +Integration points: +- Consumes ai.js for model responses +- Leverages prompt.js to tailor coaching content +- References analyze.js outputs to give precise feedback + +Personalized coaching features: +- Tailored to candidate’s resume highlights and gaps +- Adjusts difficulty and tone based on user preferences +- Suggests STAR-based improvements and concrete examples + +**Section sources** +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) + +### ResultView +Responsibilities: +- Display per-question and overall scores +- Show strengths, gaps, and recommended next steps +- Present tone insights and communication style adjustments +- Allow export or sharing of results + +Data inputs: +- Scores from scoring.js +- Tone metrics from tone.js +- Analytical breakdowns from analyze.js + +Visualization elements: +- Dimensional radar or bar charts +- Actionable bullet points +- Progress trends across sessions + +**Section sources** +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) + +### AI Integration Layer (ai.js) +Responsibilities: +- Manage API calls to language models +- Handle retries, timeouts, and error states +- Stream responses if supported +- Normalize model outputs for downstream processing + +Error handling: +- Graceful fallbacks when models are unavailable +- User-friendly messages and retry prompts + +**Section sources** +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) + +### Prompt Builder (prompt.js) +Responsibilities: +- Construct prompts based on role, seniority, industry, and resume context +- Inject constraints (length, format, focus areas) +- Support multiple templates for different question types + +Dynamic variables: +- Job description keywords +- Resume skills and experiences +- Target company culture cues + +**Section sources** +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) + +### Response Analyzer (analyze.js) +Responsibilities: +- Parse candidate answers into structured dimensions +- Detect presence of STAR elements, quantification, and relevance +- Identify missing information and suggest improvements + +Complexity considerations: +- Efficient parsing to avoid blocking UI +- Scalable to long-form answers + +**Section sources** +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) + +### Tone Evaluator (tone.js) +Responsibilities: +- Assess confidence, clarity, empathy, and professionalism +- Provide actionable tone adjustments +- Track tone trends across sessions + +Metrics: +- Confidence score +- Clarity index +- Empathy indicator +- Professionalism rating + +**Section sources** +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) + +### Scoring Engine (scoring.js) +Responsibilities: +- Aggregate analysis and tone metrics into final scores +- Weight dimensions by role requirements +- Generate recommendations and next steps + +Weighting strategy: +- Role-specific importance (e.g., leadership vs technical depth) +- Adaptive weighting based on user goals + +**Section sources** +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) + +### Persistence (supabase.js) +Responsibilities: +- Store session metadata, questions, answers, scores, and tone insights +- Retrieve historical performance for progress tracking +- Sync across devices if enabled + +Security and privacy: +- Respect user consent and data retention policies +- Anonymize sensitive details where appropriate + +**Section sources** +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +### Application Shell (App.jsx, store.jsx, index.html) +Responsibilities: +- Route users to interview pages and results +- Manage global state and settings +- Load assets and initialize environment + +State management: +- Centralized store for session and user preferences +- Reactive updates across components + +**Section sources** +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [store.jsx:1-200](file://src/store.jsx#L1-L200) +- [index.html:1-200](file://index.html#L1-L200) + +## Dependency Analysis +High-level dependencies among core modules: + +```mermaid +graph LR +MIP["MockInterviewPage.jsx"] --> AI["ai.js"] +MIP --> PR["prompt.js"] +MIP --> AN["analyze.js"] +MIP --> TO["tone.js"] +MIP --> SC["scoring.js"] +MIP --> SB["supabase.js"] +RV["ResultView.jsx"] --> SC +RV --> TO +RV --> AN +AA["AiAssistant.jsx"] --> AI +AA --> PR +``` + +**Diagram sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +**Section sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +## Performance Considerations +- Batch analysis: Combine analyze.js and tone.js evaluations to reduce round-trips. +- Lazy loading: Defer heavy computations until needed. +- Streaming responses: If supported by ai.js, stream partial answers to improve perceived latency. +- Caching prompts: Reuse generated prompts for similar roles to minimize redundant work. +- Pagination of history: Load past sessions incrementally to keep UI responsive. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- AI call failures: Check network connectivity and retry logic in ai.js; ensure rate limits are respected. +- Missing resume context: Verify resume upload and parsing before starting the interview. +- Inconsistent scores: Review weighting rules in scoring.js and ensure consistent input formatting. +- Tone anomalies: Confirm text normalization and encoding; re-run tone evaluation if special characters are present. +- Persistence errors: Validate Supabase credentials and permissions in supabase.js. + +**Section sources** +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) + +## Conclusion +The AI-powered interview preparation system combines a robust mock interview interface with intelligent question generation, comprehensive response evaluation, and nuanced tone analysis. By integrating resume context, industry-specific prompts, and persistent performance tracking, it delivers personalized coaching that adapts to each candidate’s needs. Use the customization options and coaching tips to maximize improvement and confidence ahead of real interviews. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Example Interview Sessions +- Behavioral focus: Leadership and conflict resolution for engineering managers +- Technical focus: System design and trade-offs for senior software engineers +- Situational focus: Prioritization and stakeholder management for product roles + +[No sources needed since this section provides conceptual examples] + +### Customization Options +- Role and seniority levels +- Industry and company type filters +- Question difficulty and depth +- Emphasis on behavioral vs technical vs situational questions +- Coaching style (direct, supportive, Socratic) + +[No sources needed since this section provides conceptual options] + +### Tips for Maximizing AI Coaching Effectiveness +- Prepare a detailed resume and target job description +- Practice consistently and review results after each session +- Focus on weak dimensions identified by scoring and tone analysis +- Incorporate AI-suggested improvements into subsequent attempts +- Track progress over time to measure growth + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/Mock Interview Interface.md b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/Mock Interview Interface.md new file mode 100644 index 0000000..640eeb3 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/Mock Interview Interface.md @@ -0,0 +1,298 @@ +# Mock Interview Interface + + +**Referenced Files in This Document** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the mock interview interface component, focusing on how users initiate sessions, navigate questions, provide answers, and review performance. It covers user interaction flows, question display mechanisms, response input handling, session management, customization options (difficulty levels and job categories), real-time feedback, integration with resume data for personalized questions, and the scoring system used to evaluate responses. + +## Project Structure +The mock interview feature is implemented primarily as a React application with: +- A page-level component that orchestrates the interview flow +- A results view for post-interview review +- An AI assistant component for guidance and hints +- Libraries for AI prompting, scoring, and global state management + +```mermaid +graph TB +App["App.jsx"] --> Page["MockInterviewPage.jsx"] +Page --> Result["ResultView.jsx"] +Page --> Assistant["AiAssistant.jsx"] +Page --> Store["store.jsx"] +Page --> Scoring["scoring.js"] +Page --> AI["ai.js"] +Page --> Prompt["prompt.js"] +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) + +## Core Components +- MockInterviewPage: Main orchestration of the interview lifecycle, including session setup, question navigation, answer capture, and result generation. +- ResultView: Displays final scores, breakdowns, and actionable insights after an interview session. +- AiAssistant: Provides contextual help, hints, and explanations during the interview. +- scoring.js: Implements evaluation logic and scoring algorithms for responses. +- ai.js: Handles communication with AI services for generating questions and evaluating answers. +- prompt.js: Centralizes prompts used to generate personalized questions based on resume and configuration. +- store.jsx: Manages global state such as current session, active question index, answers, and settings. + +Key responsibilities: +- Session initialization from resume and preferences +- Question rendering and navigation controls +- Answer input handling and validation +- Real-time feedback via AI assistant +- Post-session scoring and result visualization + +**Section sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview +The mock interview interface follows a component-driven architecture with clear separation between UI orchestration, AI interactions, and scoring logic. + +```mermaid +sequenceDiagram +participant User as "User" +participant Page as "MockInterviewPage.jsx" +participant Store as "store.jsx" +participant AI as "ai.js" +participant Prompt as "prompt.js" +participant Score as "scoring.js" +participant Result as "ResultView.jsx" +User->>Page : "Start Interview" +Page->>Store : "Initialize session with resume + settings" +Page->>Prompt : "Build personalized prompt" +Prompt-->>AI : "Request questions" +AI-->>Page : "Return questions" +loop For each question +Page->>Store : "Set active question" +User->>Page : "Provide answer" +Page->>Score : "Evaluate answer" +Score-->>Page : "Scores and feedback" +Page->>Result : "Update live preview" +end +Page->>Result : "Render final results" +``` + +**Diagram sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [store.jsx](file://src/store.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Detailed Component Analysis + +### MockInterviewPage +Responsibilities: +- Initializes interview sessions using resume data and user preferences (job category, difficulty). +- Generates questions by composing prompts and calling AI services. +- Manages navigation through questions and captures user answers. +- Integrates real-time feedback via the AI assistant. +- Triggers scoring and transitions to results. + +User interaction flow: +- Start screen collects or loads resume data and selects interview type and difficulty. +- Each question is displayed with context and optional hints. +- Users submit answers; the system evaluates and provides immediate feedback. +- After completing all questions, the user reviews detailed results. + +Customization options: +- Job categories influence question domains and focus areas. +- Difficulty levels adjust question complexity and evaluation criteria. + +Real-time feedback: +- The AI assistant can offer hints, clarifications, and partial evaluations while answering. + +Session management: +- Stores current question index, answers, and metadata in global state. +- Persists progress to allow resuming interrupted sessions. + +**Section sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [store.jsx](file://src/store.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +### ResultView +Responsibilities: +- Aggregates scores per question and overall performance metrics. +- Presents strengths, weaknesses, and improvement suggestions. +- Allows exporting or sharing results. + +Data presentation: +- Breakdown by category and difficulty. +- Visual indicators for trends and areas needing attention. + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [scoring.js](file://src/lib/scoring.js) + +### AiAssistant +Responsibilities: +- Provides contextual help and hints during interviews. +- Can summarize key points or suggest structures for answers. +- Offers explanations for scoring feedback. + +Integration: +- Consumes AI capabilities via shared libraries and prompts. + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +### Scoring System (scoring.js) +Responsibilities: +- Evaluates answers against expected criteria derived from prompts and domain knowledge. +- Produces per-question scores and aggregated metrics. +- Generates actionable feedback text. + +Evaluation dimensions: +- Relevance to question and resume alignment. +- Depth and clarity of explanation. +- Use of relevant examples and terminology. + +Scoring outputs: +- Numeric score per dimension. +- Composite score across dimensions. +- Feedback messages tailored to user’s profile. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) + +### AI Integration (ai.js and prompt.js) +Responsibilities: +- ai.js: Encapsulates calls to AI services for question generation and answer evaluation. +- prompt.js: Defines templates and strategies for building personalized prompts based on resume and settings. + +Personalization: +- Resume parsing informs targeted questions and evaluation rubrics. +- Job category and difficulty adjust prompt parameters. + +Error handling: +- Retries and fallbacks for AI service failures. +- Graceful degradation when AI is unavailable. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) + +### Global State Management (store.jsx) +Responsibilities: +- Holds session state: resume data, settings, current question index, answers, and scores. +- Provides actions to update state consistently across components. +- Ensures persistence and recovery of session data. + +State shape highlights: +- Session metadata (start time, duration, settings). +- Questions array with IDs and content. +- Answers map keyed by question ID. +- Scores object with per-question and aggregate metrics. + +**Section sources** +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis +The following diagram shows how components depend on libraries and each other: + +```mermaid +graph LR +Page["MockInterviewPage.jsx"] --> Store["store.jsx"] +Page --> AI["ai.js"] +Page --> Prompt["prompt.js"] +Page --> Score["scoring.js"] +Page --> Result["ResultView.jsx"] +Page --> Assistant["AiAssistant.jsx"] +Assistant --> AI +Assistant --> Prompt +Result --> Score +``` + +**Diagram sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [store.jsx](file://src/store.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +**Section sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [store.jsx](file://src/store.jsx) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Performance Considerations +- Batched updates: Minimize re-renders by grouping state updates for question navigation and answer submission. +- Lazy loading: Load AI-generated questions only when needed to reduce initial load time. +- Caching: Cache frequently used prompts and common question templates to avoid redundant AI calls. +- Debounced feedback: Throttle real-time feedback requests to prevent excessive network usage. +- Efficient scoring: Precompute reusable scoring weights and avoid recalculating unchanged sections. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- AI service errors: Implement retries with exponential backoff and fallback to cached questions if available. +- Missing resume data: Validate required fields before starting the interview and prompt users to upload or complete their profile. +- Stuck sessions: Provide a “Resume last session” option and ensure state persistence across reloads. +- Inconsistent scoring: Log evaluation inputs and outputs for debugging; verify prompt parameters align with selected difficulty and job category. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [scoring.js](file://src/lib/scoring.js) +- [store.jsx](file://src/store.jsx) + +## Conclusion +The mock interview interface integrates resume-based personalization, customizable settings, real-time AI assistance, and robust scoring to deliver a comprehensive practice experience. By separating concerns across components and libraries, the system remains maintainable and extensible, allowing future enhancements such as additional interview types, richer analytics, and improved accessibility. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/Tone Analysis & Response Evaluation.md b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/Tone Analysis & Response Evaluation.md new file mode 100644 index 0000000..a91b1e3 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/AI Interview Preparation/Tone Analysis & Response Evaluation.md @@ -0,0 +1,434 @@ +# Tone Analysis & Response Evaluation + + +**Referenced Files in This Document** +- [tone.js](file://src/lib/tone.js) +- [scoring.js](file://src/lib/scoring.js) +- [ai.js](file://src/lib/ai.js) +- [prompt.js](file://src/lib/prompt.js) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [System Architecture](#system-architecture) +3. [Core Components](#core-components) +4. [Tone Analysis Engine](#tone-analysis-engine) +5. [Scoring Algorithms](#scoring-algorithms) +6. [Feedback Generation System](#feedback-generation-system) +7. [AI Integration Layer](#ai-integration-layer) +8. [User Interface Components](#user-interface-components) +9. [Evaluation Criteria](#evaluation-criteria) +10. [Performance Optimization](#performance-optimization) +11. [Troubleshooting Guide](#troubleshooting-guide) +12. [Conclusion](#conclusion) + +## Introduction + +The Tone Analysis & Response Evaluation system is a sophisticated AI-powered platform designed to analyze candidate responses during mock interviews, providing comprehensive feedback on communication effectiveness, confidence levels, clarity, and professionalism. The system leverages advanced natural language processing techniques and machine learning algorithms to deliver actionable insights that help candidates improve their interview performance. + +This documentation provides an in-depth technical overview of the system's architecture, scoring algorithms, feedback generation mechanisms, and integration points with AI services. + +## System Architecture + +The system follows a modular architecture pattern with clear separation of concerns between tone analysis, scoring algorithms, feedback generation, and user interface components. + +```mermaid +graph TB +subgraph "Frontend Layer" +UI[User Interface] +MockInterview[Mock Interview Page] +ResultView[Results Display] +AiAssistant[AI Assistant] +end +subgraph "Analysis Layer" +ToneAnalyzer[Tone Analysis Engine] +ScoringEngine[Scoring Algorithm] +FeedbackGen[Feedback Generator] +end +subgraph "AI Integration Layer" +AIClient[AI Client] +PromptManager[Prompt Manager] +AISupabase[AISupabase Proxy] +end +subgraph "Data Layer" +Storage[Local Storage] +SupabaseDB[(Supabase Database)] +end +UI --> MockInterview +MockInterview --> ToneAnalyzer +MockInterview --> ResultView +MockInterview --> AiAssistant +ToneAnalyzer --> ScoringEngine +ScoringEngine --> FeedbackGen +ToneAnalyzer --> AIClient +AIClient --> AISupabase +AIClient --> PromptManager +ResultView --> Storage +AiAssistant --> SupabaseDB +``` + +**Diagram sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [tone.js:1-150](file://src/lib/tone.js#L1-L150) +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) +- [ai.js:1-100](file://src/lib/ai.js#L1-L100) + +## Core Components + +### Tone Analysis Engine +The tone analysis engine serves as the core component responsible for evaluating candidate responses across multiple dimensions including confidence, clarity, professionalism, and communication effectiveness. + +### Scoring Algorithm +The scoring algorithm processes tone analysis results and generates quantitative scores using weighted multi-factor evaluation methods. + +### Feedback Generation System +The feedback generator transforms analytical data into actionable insights and improvement suggestions for candidates. + +### AI Integration Layer +The AI integration layer manages communication with external AI services through a proxy system for enhanced security and rate limiting. + +**Section sources** +- [tone.js:1-150](file://src/lib/tone.js#L1-L150) +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) +- [ai.js:1-100](file://src/lib/ai.js#L1-L100) + +## Tone Analysis Engine + +The tone analysis engine implements a comprehensive framework for evaluating candidate responses across four primary dimensions: + +### Confidence Assessment +The confidence analysis evaluates linguistic patterns, word choice, sentence structure, and rhetorical devices to determine the candidate's self-assurance level. Key indicators include: +- Use of definitive language vs. hedging phrases +- Sentence length and complexity +- Active vs. passive voice usage +- Presence of filler words and hesitation markers + +### Clarity Evaluation +Clarity assessment focuses on the logical flow of ideas, coherence of arguments, and precision of communication. The system analyzes: +- Logical connectors and transition words +- Paragraph organization and structure +- Redundancy and repetition detection +- Ambiguity identification + +### Professionalism Measurement +Professionalism evaluation examines adherence to business communication standards, appropriate language use, and contextual awareness. Metrics include: +- Formality level assessment +- Industry-specific terminology usage +- Cultural sensitivity indicators +- Appropriate tone maintenance + +### Communication Effectiveness +Communication effectiveness measures overall impact and persuasiveness of the response. Factors analyzed: +- Storytelling elements and narrative structure +- Persuasive techniques employed +- Audience engagement strategies +- Call-to-action presence + +```mermaid +flowchart TD +Input[Raw Candidate Response] --> Preprocess["Text Preprocessing
- Tokenization
- Stopword Removal
- Normalization"] +Preprocess --> Confidence["Confidence Analysis
- Linguistic Patterns
- Word Choice
- Sentence Structure"] +Preprocess --> Clarity["Clarity Analysis
- Logical Flow
- Coherence
- Precision"] +Preprocess --> Professionalism["Professionalism Analysis
- Formality Level
- Business Language
- Context Awareness"] +Preprocess --> Effectiveness["Effectiveness Analysis
- Impact Assessment
- Persuasiveness
- Engagement"] +Confidence --> ScoreCalc["Score Calculation"] +Clarity --> ScoreCalc +Professionalism --> ScoreCalc +Effectiveness --> ScoreCalc +ScoreCalc --> WeightedSum["Weighted Summation"] +WeightedSum --> FinalScores["Final Analysis Scores"] +``` + +**Diagram sources** +- [tone.js:1-150](file://src/lib/tone.js#L1-L150) + +**Section sources** +- [tone.js:1-150](file://src/lib/tone.js#L1-L150) + +## Scoring Algorithms + +The scoring system employs a sophisticated multi-factor evaluation approach that combines quantitative metrics with qualitative assessments to generate comprehensive performance scores. + +### Weighted Scoring Model +The system uses a weighted scoring model where different aspects contribute differently to the final score: + +| Dimension | Weight | Description | +|-----------|--------|-------------| +| Confidence | 25% | Self-assurance and conviction in responses | +| Clarity | 30% | Logical flow and communication precision | +| Professionalism | 25% | Business appropriateness and formal language | +| Effectiveness | 20% | Overall impact and persuasiveness | + +### Normalization Process +Raw scores undergo normalization to ensure consistency across different question types and difficulty levels: + +```mermaid +sequenceDiagram +participant Raw as "Raw Scores" +participant Norm as "Normalization Engine" +participant Weight as "Weight Calculator" +participant Final as "Final Scores" +Raw->>Norm : Input raw dimension scores +Norm->>Norm : Apply statistical normalization +Norm->>Weight : Pass normalized scores +Weight->>Weight : Apply dimension weights +Weight->>Final : Generate weighted scores +Final-->>Final : Calculate composite score +``` + +**Diagram sources** +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) + +### Adaptive Scoring +The system implements adaptive scoring that adjusts weightings based on: +- Question type (behavioral, technical, situational) +- Role requirements and seniority level +- Industry-specific communication standards +- Historical performance trends + +**Section sources** +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) + +## Feedback Generation System + +The feedback generation system transforms analytical data into actionable insights through a multi-stage process that ensures relevance, specificity, and practical applicability. + +### Insight Extraction Pipeline +The system extracts key insights from analysis results and categorizes them into improvement areas: + +```mermaid +flowchart LR +Analysis["Analysis Results"] --> Pattern["Pattern Recognition"] +Pattern --> Categorize["Category Assignment"] +Categorize --> Prioritize["Priority Ranking"] +Prioritize --> Generate["Feedback Generation"] +Generate --> Actionable["Actionable Insights"] +subgraph "Categories" +P1["Communication Style"] +P2["Content Structure"] +P3["Delivery Method"] +P4["Professional Presence"] +end +Categorize --> P1 +Categorize --> P2 +Categorize --> P3 +Categorize --> P4 +``` + +**Diagram sources** +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) + +### Personalized Recommendations +The system generates personalized improvement suggestions based on: +- Individual performance patterns +- Comparison with industry benchmarks +- Role-specific communication requirements +- Historical progress tracking + +### Improvement Roadmap +Candidates receive structured improvement plans with: +- Specific action items with measurable outcomes +- Practice exercises tailored to weak areas +- Progress tracking mechanisms +- Milestone-based achievement validation + +**Section sources** +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) + +## AI Integration Layer + +The AI integration layer provides secure and efficient access to external artificial intelligence services through a centralized proxy system. + +### AI Service Architecture +The system utilizes a proxy-based architecture to manage AI service communications: + +```mermaid +classDiagram +class AIClient { ++makeRequest(prompt, context) Promise ++handleResponse(response) Object ++validateApiKey() Boolean +-formatPrompt(prompt) String +-parseResponse(data) Object +} +class AISupabaseProxy { ++proxyRequest(request) Promise ++rateLimitCheck() Boolean ++errorHandling(error) Error +-logRequest(request) void +-monitorUsage() void +} +class PromptManager { ++getTemplate(type) String ++customizePrompt(template, context) String ++validatePrompt(prompt) Boolean +-loadTemplates() Array +} +AIClient --> AISupabaseProxy : "uses" +AIClient --> PromptManager : "uses" +AISupabaseProxy --> AIClient : "returns" +``` + +**Diagram sources** +- [ai.js:1-100](file://src/lib/ai.js#L1-L100) +- [supabase/functions/ai-proxy/index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +### Security and Rate Limiting +The proxy layer implements comprehensive security measures: +- API key management and rotation +- Request authentication and authorization +- Rate limiting and throttling +- Error handling and retry mechanisms +- Usage monitoring and logging + +### Custom Analysis Rules +The system supports custom analysis rules that can be configured without code changes: + +| Rule Type | Purpose | Configuration | +|-----------|---------|---------------| +| Keyword Detection | Identify specific terms/phrases | Regex patterns | +| Sentiment Analysis | Evaluate emotional tone | ML model parameters | +| Structural Analysis | Assess response organization | Template definitions | +| Domain-Specific Rules | Industry-specific criteria | Custom rule sets | + +**Section sources** +- [ai.js:1-100](file://src/lib/ai.js#L1-L100) +- [supabase/functions/ai-proxy/index.ts:1-200](file://supabase/functions/ai-proxy/index.ts#L1-L200) + +## User Interface Components + +The user interface provides intuitive interaction points for candidates to engage with the tone analysis system and view their performance evaluations. + +### Mock Interview Interface +The mock interview page serves as the primary interaction point for candidates: + +```mermaid +sequenceDiagram +participant Candidate as "Candidate" +participant UI as "MockInterviewPage" +participant Analyzer as "Tone Analyzer" +participant Scorer as "Scoring Engine" +participant Display as "ResultView" +Candidate->>UI : Start Interview Session +UI->>Analyzer : Submit Response +Analyzer->>Analyzer : Analyze Tone & Content +Analyzer->>Scorer : Calculate Scores +Scorer->>Display : Generate Results +Display-->>Candidate : Show Performance Metrics +Display-->>Candidate : Provide Feedback +``` + +**Diagram sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [ResultView.jsx:1-150](file://src/components/ResultView.jsx#L1-L150) + +### Results Visualization +The results display component presents comprehensive performance analytics through interactive visualizations: +- Real-time score updates +- Comparative analysis charts +- Progress tracking over time +- Detailed breakdown of individual metrics + +### AI Assistant Integration +The AI assistant provides contextual guidance and additional support throughout the interview process: + +**Section sources** +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [ResultView.jsx:1-150](file://src/components/ResultView.jsx#L1-L150) +- [AiAssistant.jsx:1-100](file://src/components/AiAssistant.jsx#L1-L100) + +## Evaluation Criteria + +The system employs comprehensive evaluation criteria across multiple dimensions to provide holistic assessment of candidate performance. + +### Confidence Indicators +- **Language Certainty**: Use of definitive statements vs. hesitant language +- **Body Language Cues**: Vocal confidence markers and speech patterns +- **Experience Assertion**: How candidates present their qualifications and achievements +- **Decision-Making Presentation**: Demonstration of confident decision-making processes + +### Clarity Metrics +- **Logical Structure**: Organization and flow of ideas within responses +- **Conciseness**: Ability to communicate effectively without unnecessary verbosity +- **Specificity**: Use of concrete examples and measurable outcomes +- **Audience Awareness**: Adaptation of communication style to interviewer expectations + +### Professionalism Standards +- **Business Etiquette**: Adherence to professional communication norms +- **Industry Terminology**: Appropriate use of field-specific language +- **Cultural Sensitivity**: Awareness of diverse communication preferences +- **Ethical Considerations**: Demonstrating integrity and ethical reasoning + +### Communication Effectiveness +- **Storytelling Ability**: Engaging narrative structure in responses +- **Persuasive Techniques**: Use of evidence and logical arguments +- **Emotional Intelligence**: Reading and responding to interviewer cues +- **Adaptability**: Adjusting communication style based on context + +**Section sources** +- [tone.js:1-150](file://src/lib/tone.js#L1-L150) +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) + +## Performance Optimization + +The system implements several optimization strategies to ensure responsive and efficient tone analysis: + +### Caching Mechanisms +- **Response Caching**: Store frequently analyzed response patterns +- **Score Caching**: Cache computed scores for similar input patterns +- **Template Caching**: Pre-load AI prompt templates for faster processing + +### Parallel Processing +- **Multi-threaded Analysis**: Process multiple response dimensions simultaneously +- **Asynchronous AI Calls**: Non-blocking requests to external AI services +- **Batch Processing**: Group related analysis tasks for efficiency + +### Memory Management +- **Stream Processing**: Handle large text inputs without memory overflow +- **Garbage Collection**: Efficient cleanup of temporary analysis objects +- **Resource Pooling**: Reuse connections to external services + +### Scalability Considerations +- **Horizontal Scaling**: Support for multiple concurrent users +- **Load Balancing**: Distribute analysis requests across available resources +- **Database Optimization**: Efficient storage and retrieval of historical data + +## Troubleshooting Guide + +Common issues and their resolution strategies when working with the tone analysis system: + +### AI Service Connectivity Issues +- **Symptoms**: Timeout errors, connection failures, or inconsistent responses +- **Solutions**: Verify API keys, check network connectivity, implement retry logic +- **Prevention**: Monitor service health, implement circuit breakers + +### Analysis Accuracy Problems +- **Symptoms**: Inconsistent scoring, unexpected results, or biased evaluations +- **Solutions**: Review analysis rules, update training data, adjust weighting factors +- **Prevention**: Regular model retraining, continuous quality assurance + +### Performance Bottlenecks +- **Symptoms**: Slow response times, high memory usage, or system lag +- **Solutions**: Optimize caching strategies, implement lazy loading, review database queries +- **Prevention**: Load testing, performance monitoring, resource allocation planning + +### Data Synchronization Issues +- **Symptoms**: Lost analysis results, inconsistent user data, or sync failures +- **Solutions**: Implement conflict resolution, verify data integrity, restore from backups +- **Prevention**: Robust error handling, transaction management, regular backups + +**Section sources** +- [ai.js:1-100](file://src/lib/ai.js#L1-L100) +- [scoring.js:1-120](file://src/lib/scoring.js#L1-L120) + +## Conclusion + +The Tone Analysis & Response Evaluation system represents a comprehensive solution for enhancing interview preparation through intelligent analysis and feedback. By combining advanced natural language processing, machine learning algorithms, and user-centric design, the system provides candidates with actionable insights that drive meaningful improvement in their communication skills. + +The modular architecture ensures scalability and maintainability, while the AI integration layer provides flexibility for future enhancements and customizations. The system's emphasis on actionable feedback and progressive improvement aligns with best practices in educational technology and professional development platforms. + +Future enhancements may include expanded language support, more sophisticated behavioral analysis, integration with additional assessment frameworks, and enhanced personalization capabilities based on individual learning patterns and career goals. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Core Features.md b/.qoder/repowiki/en/content/Core Features/Core Features.md new file mode 100644 index 0000000..b0eb860 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Core Features.md @@ -0,0 +1,534 @@ +# Core Features + + +**Referenced Files in This Document** +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [auth.jsx](file://src/auth.jsx) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [storage.js](file://src/lib/storage.js) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [pricing.js](file://src/lib/pricing.js) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [csv.js](file://src/lib/csv.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [config.toml](file://supabase/config.toml) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [http.ts](file://supabase/functions/_shared/http.ts) +- [entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [prompts.ts](file://supabase/functions/_shared/prompts.ts) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion + +## Introduction +This document explains the core features of ApplyGuard PH: +- Job Application Tracker Dashboard +- AI-Powered Interview Preparation System +- Offer Comparison Tools +- AI Assistant Functionality + +It covers user workflows, feature interactions, shared data models, configuration options, and customization possibilities. The goal is to help both technical and non-technical users understand how the application works end-to-end. + +## Project Structure +The application is a modern web app with React components on the frontend, Supabase for backend services (database, functions), and local storage for offline-first capabilities. Key areas: +- Frontend UI and state management under src/components and src/store.jsx +- Feature logic and utilities under src/lib +- Backend schema and serverless functions under supabase +- Configuration files at the root and under supabase + +```mermaid +graph TB +subgraph "Frontend" +A["App.jsx"] +B["components/*"] +C["lib/*"] +D["store.jsx"] +end +subgraph "Backend" +E["Supabase Functions
ai-proxy, billing, etc."] +F["Database Schema
migrations/*.sql"] +G["Config
config.toml"] +end +A --> B +B --> C +B --> D +C --> E +C --> F +C --> G +``` + +[No sources needed since this diagram shows conceptual structure] + +## Core Components +- App.jsx: Top-level routing and layout orchestration +- store.jsx: Global state and cross-feature data sharing +- Tracker.jsx: Job application tracker dashboard +- MockInterviewPage.jsx: AI-powered interview preparation +- OffersPage.jsx: Offer comparison tools +- AiAssistant.jsx: Conversational AI assistant +- Settings.jsx: User preferences and feature toggles +- ResultView.jsx: Results display for analysis and scoring +- ScanForm.jsx: Input form for resume or job description scanning + +These components integrate via shared libraries (ai.js, analyze.js, scoring.js, stats.js, followups.js, redflags.js, prompt.js, tone.js) and persist data through storage.js and sync.js, with optional cloud sync via supabase.js. + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +## Architecture Overview +ApplyGuard PH follows a layered architecture: +- Presentation layer: React components +- Domain logic: Feature-specific utilities and AI integration +- Data layer: Local storage, optional Supabase sync, and database schema +- Integration layer: Serverless functions for AI proxy and billing + +```mermaid +graph TB +UI["UI Components
Tracker, MockInterview, Offers, AiAssistant"] +State["Global Store
store.jsx"] +Libs["Feature Libraries
ai.js, analyze.js, scoring.js,
stats.js, followups.js, redflags.js,
prompt.js, tone.js"] +Storage["Local Storage
storage.js"] +Sync["Sync Layer
sync.js, supabase.js"] +DB["Supabase Database
migrations/*.sql"] +Funcs["Supabase Functions
ai-proxy, billing, etc."] +UI --> State +UI --> Libs +Libs --> Storage +Libs --> Sync +Sync --> DB +Libs --> Funcs +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) + +## Detailed Component Analysis + +### Job Application Tracker Dashboard +Purpose: Track applications, statuses, notes, and next actions; visualize progress and generate insights. + +User workflow: +- Add or import applications +- Update status and add notes +- View analytics and suggestions +- Export or share summaries + +Key interactions: +- Tracker component orchestrates CRUD operations +- Stats and scoring libraries compute metrics +- Follow-ups and red flags provide actionable insights +- Storage persists locally; sync optionally pushes to Supabase + +```mermaid +sequenceDiagram +participant U as "User" +participant T as "Tracker.jsx" +participant S as "store.jsx" +participant ST as "stats.js" +participant SC as "scoring.js" +participant FL as "followups.js" +participant RF as "redflags.js" +participant LO as "storage.js" +participant SY as "sync.js" +U->>T : "Add/Update Application" +T->>S : "Dispatch update" +S->>LO : "Persist locally" +S->>SY : "Optional cloud sync" +T->>ST : "Compute metrics" +T->>SC : "Score applications" +T->>FL : "Generate follow-up tasks" +T->>RF : "Check red flags" +T-->>U : "Dashboard view with insights" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +Configuration and customization: +- Status categories and labels can be configured via settings +- Scoring weights and thresholds adjustable in scoring library +- Follow-up rules customizable in follow-ups module +- Red flag detection parameters tunable in redflags module + +Data model highlights: +- Applications include identifiers, company, role, status, dates, notes, scores, and follow-up items +- Analytics aggregate counts, conversion rates, and time-in-stage metrics + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +### AI-Powered Interview Preparation System +Purpose: Generate mock interviews, questions, and feedback using AI prompts and analysis. + +User workflow: +- Select role or paste job description +- Configure difficulty and focus areas +- Start mock session and receive questions +- Review answers and get feedback + +Key interactions: +- MockInterviewPage coordinates session flow +- ai.js handles AI calls via Supabase functions +- prompt.js builds structured prompts +- analyze.js and scoring.js evaluate responses +- ResultView displays outcomes + +```mermaid +sequenceDiagram +participant U as "User" +participant M as "MockInterviewPage.jsx" +participant P as "prompt.js" +participant A as "ai.js" +participant F as "ai-proxy/index.ts" +participant AN as "analyze.js" +participant SC as "scoring.js" +participant RV as "ResultView.jsx" +U->>M : "Configure session" +M->>P : "Build prompt" +M->>A : "Request AI generation" +A->>F : "Call function" +F-->>A : "AI response" +A-->>M : "Questions/Feedback" +M->>AN : "Analyze answers" +M->>SC : "Score performance" +M-->>RV : "Render results" +``` + +**Diagram sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +Configuration and customization: +- Prompt templates and styles configurable in prompt.js +- Tone and style adjustments in tone.js +- Difficulty levels and question categories adjustable in MockInterviewPage +- Scoring rubrics tuned in scoring.js + +Data model highlights: +- Sessions include role, difficulty, generated questions, user answers, and scores +- Feedback includes strengths, weaknesses, and improvement tips + +**Section sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### Offer Comparison Tools +Purpose: Compare multiple offers side-by-side, score them, and visualize trade-offs. + +User workflow: +- Add offers with compensation, benefits, and conditions +- Adjust weights for criteria (salary, growth, location, etc.) +- View comparative scores and recommendations + +Key interactions: +- OffersPage manages offer entries and comparisons +- scoring.js computes weighted scores +- stats.js provides summary metrics +- storage.js persists offers; sync.js optionally syncs + +```mermaid +flowchart TD +Start(["Start Comparison"]) --> AddOffer["Add Offer Details"] +AddOffer --> SetWeights["Set Criteria Weights"] +SetWeights --> ComputeScores["Compute Weighted Scores"] +ComputeScores --> Visualize["Visualize Comparisons"] +Visualize --> Save["Save Locally / Sync"] +Save --> End(["End"]) +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +Configuration and customization: +- Criteria list and default weights configurable in OffersPage +- Scoring formulas adjustable in scoring.js +- Visualization options controlled by UI props + +Data model highlights: +- Offers include base salary, bonuses, equity, benefits, location, growth potential, and custom fields +- Scores reflect weighted aggregation across criteria + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +### AI Assistant Functionality +Purpose: Provide conversational assistance for job search strategy, resume tips, interview prep, and offer negotiation. + +User workflow: +- Open AiAssistant +- Ask questions or request guidance +- Receive contextual advice based on stored applications and offers + +Key interactions: +- AiAssistant composes prompts using prompt.js and tone.js +- ai.js routes requests to ai-proxy function +- Context may include recent applications, scores, and follow-ups + +```mermaid +sequenceDiagram +participant U as "User" +participant AA as "AiAssistant.jsx" +participant PR as "prompt.js" +participant TN as "tone.js" +participant AI as "ai.js" +participant FP as "ai-proxy/index.ts" +U->>AA : "Ask question" +AA->>PR : "Build context-aware prompt" +AA->>TN : "Adjust tone/style" +AA->>AI : "Send request" +AI->>FP : "Call function" +FP-->>AI : "Response" +AI-->>AA : "Assistant reply" +AA-->>U : "Display answer" +``` + +**Diagram sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) + +Configuration and customization: +- Prompt templates and system instructions in prompt.js +- Tone presets and style modifiers in tone.js +- Access controls and entitlement checks via entitlement.js and billing.js + +Data model highlights: +- Assistant maintains conversation history and references relevant application/offer data +- Responses are not persisted by default unless explicitly saved by the user + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) + +### Shared Data Models and Cross-Feature Integration +Common entities: +- Application: id, company, role, status, dates, notes, scores, follow-ups +- Offer: id, compensation details, benefits, location, growth factors, scores +- Session: id, role/difficulty, questions, answers, scores, feedback +- Conversation: id, messages, context references + +Integration points: +- Tracker and Offers share scoring and stats modules +- MockInterview and AiAssistant share prompt and AI integration layers +- All features use storage and sync for persistence and optional cloud backup + +```mermaid +erDiagram +APPLICATION { +string id PK +string company +string role +enum status +timestamp applied_at +timestamp last_updated +text notes +float score +} +OFFER { +string id PK +string company +string role +float base_salary +float bonus +float equity +text benefits +string location +float growth_potential +float score +} +SESSION { +string id PK +string role +string difficulty +json questions +json answers +float score +text feedback +} +CONVERSATION { +string id PK +json messages +string context_ref +} +APPLICATION ||--o{ FOLLOWUP : "has" +OFFER ||--o{ SCORE_DETAIL : "includes" +SESSION ||--o{ FEEDBACK_ITEM : "produces" +CONVERSATION ||--|| USER_PREF : "uses" +``` + +[No sources needed since this diagram shows conceptual data models] + +## Dependency Analysis +High-level dependencies: +- Components depend on lib utilities for domain logic +- AI integration depends on ai-proxy function and shared HTTP helpers +- Billing and entitlements gate advanced features +- Storage and sync manage persistence and cloud consistency + +```mermaid +graph TB +Comp["Components
Tracker, MockInterview, Offers, AiAssistant"] +Lib["Libraries
ai, analyze, scoring, stats,
followups, redflags, prompt, tone"] +Ent["Entitlement & Billing
entitlement.js, billing.js"] +Stor["Storage & Sync
storage.js, sync.js, supabase.js"] +Func["Functions
ai-proxy, billing endpoints"] +Comp --> Lib +Lib --> Ent +Lib --> Stor +Lib --> Func +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [tone.js](file://src/lib/tone.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) + +**Section sources** +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [ai.js](file://src/lib/ai.js) +- [index.ts](file://supabase/functions/ai-proxy/index.ts) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) + +## Performance Considerations +- Prefer local storage for frequent reads/writes; batch sync operations to reduce network overhead +- Cache AI responses where appropriate to avoid redundant calls +- Optimize scoring computations by memoizing heavy calculations +- Use pagination or virtualization for large lists in Tracker and Offers views +- Keep prompt payloads concise to reduce latency and costs + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- AI proxy failures: Check function availability and error logs; verify entitlements and billing status +- Sync conflicts: Ensure consistent timestamps and merge strategies; review sync logs +- Storage errors: Validate JSON serialization and size limits; clear corrupted entries if necessary +- Scoring anomalies: Inspect input data quality and weight configurations; validate scoring formulas + +Operational hooks: +- Error boundaries and toast notifications for user feedback +- Logging utilities in libraries for debugging +- Share/export utilities for diagnostics + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [ai.js](file://src/lib/ai.js) +- [sync.js](file://src/lib/sync.js) +- [storage.js](file://src/lib/storage.js) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [csv.js](file://src/lib/csv.js) + +## Conclusion +ApplyGuard PH integrates a robust job application tracker, AI-driven interview preparation, offer comparison tools, and an AI assistant into a cohesive platform. Shared libraries ensure consistent scoring, analytics, and AI behavior across features. Users can customize prompts, tones, scoring weights, and follow-up rules to tailor the experience. With local-first storage and optional cloud sync, the app balances responsiveness and reliability. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Analytics & Statistics.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Analytics & Statistics.md new file mode 100644 index 0000000..5c08f4e --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Analytics & Statistics.md @@ -0,0 +1,390 @@ +# Analytics & Statistics + + +**Referenced Files in This Document** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the analytics and statistics features implemented in the application, focusing on metrics computation, success rates, time-to-hire calculations, company analysis, trend visualization, statistical methods, chart generation, export capabilities, and performance insights. It also provides guidance for common analytics queries, custom report generation, and best practices for data visualization. + +The analytics layer is primarily implemented in client-side JavaScript modules that compute metrics from local data stores and optionally integrate with Supabase for persistence or synchronization. The UI components consume these metrics to render dashboards, charts, and reports. + +## Project Structure +Analytics-related functionality is organized under src/lib and consumed by UI components: + +- Core analytics and statistics logic: + - stats.js: Statistical computations (means, medians, percentiles, distributions). + - scoring.js: Scoring and success rate calculations. + - csv.js: Export utilities for CSV-based reporting. + - analyze.js: Aggregation and higher-level analytics functions. +- Data access: + - supabase.js: Optional integration for remote storage and sync. +- State management and UI: + - store.jsx: Centralized state for analytics data. + - Tracker.jsx: Tracks events and aggregates metrics over time. + - ResultView.jsx: Displays results and visualizations. + +```mermaid +graph TB +subgraph "Lib" +S["stats.js"] +SC["scoring.js"] +C["csv.js"] +A["analyze.js"] +SB["supabase.js"] +end +subgraph "State" +ST["store.jsx"] +end +subgraph "UI" +T["Tracker.jsx"] +RV["ResultView.jsx"] +end +T --> ST +RV --> ST +ST --> S +ST --> SC +ST --> A +ST --> C +ST --> SB +``` + +**Diagram sources** +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [analyze.js](file://src/lib/analyze.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [analyze.js](file://src/lib/analyze.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Core Components +- Statistical engine (stats.js): Provides core math utilities such as mean, median, quartiles, percentiles, standard deviation, variance, and distribution helpers used across analytics features. +- Scoring and success rates (scoring.js): Computes success indicators, pass/fail outcomes, and derived success rates based on defined thresholds and criteria. +- CSV export (csv.js): Serializes computed metrics into CSV format for sharing and external analysis. +- Analytics aggregation (analyze.js): Orchestrates higher-level analytics like time-to-hire, company breakdowns, and trend series. +- State and UI (store.jsx, Tracker.jsx, ResultView.jsx): Maintain analytics state, track events, and render visualizations and summaries. + +Key responsibilities: +- Compute robust summary statistics and distributions. +- Derive business metrics (success rates, time-to-hire). +- Aggregate and group metrics by dimensions (e.g., company). +- Generate exports and support downstream reporting. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +The analytics architecture follows a layered approach: +- Data layer: Local state and optional Supabase integration. +- Computation layer: Statistical and business metric calculators. +- Presentation layer: UI components rendering dashboards and charts. + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx / ResultView.jsx" +participant Store as "store.jsx" +participant Stats as "stats.js" +participant Score as "scoring.js" +participant Analyze as "analyze.js" +participant CSV as "csv.js" +participant DB as "supabase.js" +UI->>Store : Request metrics +Store->>Analyze : Aggregate analytics +Analyze->>Stats : Compute distributions and summaries +Analyze->>Score : Compute success rates +Analyze-->>Store : Metrics payload +Store-->>UI : Render dashboard +UI->>CSV : Export to CSV +Store->>DB : Sync metrics (optional) +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [csv.js](file://src/lib/csv.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Statistical Engine (stats.js) +Responsibilities: +- Provide deterministic and numerically stable calculations for central tendency, dispersion, and quantiles. +- Support percentile ranking and distribution binning for trend visualization. + +Common operations: +- Mean and median calculation. +- Quartile and percentile computation. +- Variance and standard deviation. +- Distribution helpers for histogram-like grouping. + +Complexity considerations: +- Sorting-based quantile computations are O(n log n). +- Streaming-friendly aggregations can be designed using running sums and counts where applicable. + +Best practices: +- Guard against empty inputs and NaN values. +- Use consistent rounding strategies for display vs. internal precision. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) + +### Scoring and Success Rates (scoring.js) +Responsibilities: +- Determine pass/fail outcomes based on configurable thresholds. +- Compute success rates per cohort, period, or dimension. + +Key concepts: +- Thresholding rules for success classification. +- Weighted or unweighted success rate aggregation. +- Handling missing or partial data gracefully. + +Edge cases: +- Zero denominators when computing rates. +- Mixed data types and null handling. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) + +### Time-to-Hire Calculations (analyze.js) +Responsibilities: +- Calculate time-to-hire metrics from event timestamps. +- Segment by role, source, or company. +- Produce trend series for monthly or weekly intervals. + +Algorithm overview: +```mermaid +flowchart TD +Start(["Start"]) --> LoadEvents["Load candidate lifecycle events"] +LoadEvents --> FilterValid{"Has start and end dates?"} +FilterValid --> |No| Skip["Skip record"] +FilterValid --> |Yes| Diff["Compute difference in days"] +Diff --> GroupBy["Group by dimension (company, role, month)"] +GroupBy --> Summarize["Summarize: mean, median, p90"] +Summarize --> Trends["Build time-series trends"] +Trends --> End(["End"]) +Skip --> End +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Company Analysis (analyze.js) +Responsibilities: +- Aggregate metrics by company name or identifier. +- Compare success rates and time-to-hire across companies. +- Identify outliers and top performers. + +Approach: +- Group records by company. +- Apply statistical summaries per group. +- Rank companies by selected KPIs. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Trend Visualization (stats.js, analyze.js) +Responsibilities: +- Prepare time-series data for charts. +- Compute rolling averages and smoothing where appropriate. +- Ensure consistent bucketing (weekly/monthly) for comparability. + +Visualization tips: +- Use line charts for continuous trends. +- Overlay confidence bands or moving averages for clarity. +- Normalize axes when comparing multiple series. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [analyze.js](file://src/lib/analyze.js) + +### Export Capabilities (csv.js) +Responsibilities: +- Serialize metrics and raw datasets to CSV. +- Include headers and metadata for traceability. +- Support multi-sheet or concatenated outputs if needed. + +Usage patterns: +- Export filtered views (by date range or company). +- Append timestamped filenames for versioning. + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) + +### State Management and UI Integration (store.jsx, Tracker.jsx, ResultView.jsx) +Responsibilities: +- Maintain analytics state and trigger recomputation on data changes. +- Track user interactions and funnel events for analytics. +- Render dashboards, tables, and charts based on computed metrics. + +Integration points: +- Subscribe to store updates and recompute metrics reactively. +- Debounce heavy computations to avoid UI jank. +- Provide hooks or selectors for specific metric slices. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### Optional Persistence and Sync (supabase.js) +Responsibilities: +- Persist computed metrics or raw events to Supabase. +- Sync across devices or sessions. +- Fetch historical data for long-term trend analysis. + +Considerations: +- Handle network errors and retries. +- Respect quotas and rate limits. +- Keep local cache in sync with server state. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) + +## Dependency Analysis +The analytics subsystem has clear separation between computation and presentation: + +```mermaid +graph LR +Store["store.jsx"] --> Stats["stats.js"] +Store --> Score["scoring.js"] +Store --> Analyze["analyze.js"] +Store --> CSV["csv.js"] +Store --> Supa["supabase.js"] +UI1["Tracker.jsx"] --> Store +UI2["ResultView.jsx"] --> Store +``` + +Observations: +- Low coupling between UI and computation via store. +- CSV export depends only on computed metrics. +- Supabase integration is optional and decoupled from core math. + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [csv.js](file://src/lib/csv.js) +- [supabase.js](file://src/lib/supabase.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [csv.js](file://src/lib/csv.js) +- [supabase.js](file://src/lib/supabase.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Performance Considerations +- Prefer memoization for expensive aggregations keyed by filters (date range, company). +- Use streaming or incremental updates for large datasets to avoid blocking the main thread. +- Batch CSV exports and compress payloads when exporting large volumes. +- Debounce user-driven filter changes before recomputing metrics. +- Cache intermediate results (e.g., grouped datasets) to reuse across multiple visualizations. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Empty or invalid date ranges: Validate inputs before computing time-to-hire; skip malformed records. +- Division by zero in success rates: Guard against zero denominators and return safe defaults. +- Out-of-memory during exports: Stream CSV rows instead of building full strings in memory. +- Stale metrics after data changes: Ensure store subscriptions trigger recomputation and invalidate caches. +- Network failures for Supabase sync: Implement retry with exponential backoff and fallback to local-only mode. + +**Section sources** +- [stats.test.js](file://src/lib/stats.test.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [csv.test.js](file://src/lib/csv.test.js) + +## Conclusion +The analytics and statistics features provide a robust foundation for measuring hiring performance, including success rates, time-to-hire, company comparisons, and trend analysis. The modular design separates computation from presentation, enabling flexible reporting and export capabilities. Following the best practices outlined here will help maintain accuracy, performance, and usability across dashboards and reports. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Common Analytics Queries +- Success rate by company: + - Group records by company, compute pass/fail ratio, and rank by success rate. +- Median time-to-hire by role: + - Filter by role, compute differences between start and end dates, then calculate median. +- Monthly trend of applications: + - Bucket events by month, count totals, and plot as a line chart. +- Top 10 companies by throughput: + - Count total candidates per company and sort descending. + +[No sources needed since this section provides general guidance] + +### Custom Report Generation +- Define report parameters (date range, dimensions, metrics). +- Build query pipeline: filter -> group -> aggregate -> summarize. +- Render tabular view and export to CSV. +- Add chart overlays (rolling average, percentiles) for deeper insight. + +[No sources needed since this section provides general guidance] + +### Data Visualization Best Practices +- Choose appropriate chart types: + - Line for trends, bar for categorical comparisons, scatter for correlations. +- Normalize axes when comparing disparate scales. +- Annotate key inflection points and outliers. +- Provide tooltips and drill-downs for detailed inspection. +- Ensure accessibility: colorblind-safe palettes and sufficient contrast. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Application CRUD Operations.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Application CRUD Operations.md new file mode 100644 index 0000000..87cf383 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Application CRUD Operations.md @@ -0,0 +1,336 @@ +# Application CRUD Operations + + +**Referenced Files in This Document** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains how application management operations are implemented within the tracker, focusing on creating, editing, and deleting job applications. It covers managing application details such as company name, position, salary, location, and custom fields; form validation; persistence to local storage; cloud synchronization; bulk operations; import/export; and data migration between devices. + +## Project Structure +The tracker’s application management spans UI components, state management, local storage, CSV utilities, and cloud sync modules: +- UI layer: Tracker component renders forms and lists for applications. +- State layer: Store provides reactive state and actions for CRUD operations. +- Persistence layer: Local storage adapter persists data offline. +- Sync layer: Cloud module and sync orchestrator handle remote synchronization. +- Import/Export: CSV utilities support bulk operations and device migration. + +```mermaid +graph TB +subgraph "UI" +T["Tracker.jsx"] +end +subgraph "State" +S["store.jsx"] +end +subgraph "Persistence" +L["storage.js"] +end +subgraph "Sync" +C["cloud.js"] +Y["sync.js"] +end +subgraph "Utilities" +V["csv.js"] +end +A["App.jsx"] --> T +T --> S +S --> L +S --> Y +Y --> C +T --> V +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [csv.js](file://src/lib/csv.js) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [csv.js](file://src/lib/csv.js) +- [App.jsx](file://src/App.jsx) + +## Core Components +- Tracker (UI): Presents the application list, creation/editing forms, and action buttons for delete, import/export, and sync controls. It validates inputs before dispatching store actions. +- Store (State): Holds the applications array and exposes actions for create, update, delete, and bulk operations. It triggers persistence and sync hooks when data changes. +- Storage (Local Persistence): Serializes and deserializes application records to/from browser storage with conflict-free keys and timestamps. +- Sync (Orchestrator): Coordinates background or manual sync cycles, batching changes and handling conflicts. +- Cloud (Remote Backend): Interfaces with the backend service for user-scoped data sharing across devices. +- CSV (Import/Export): Parses CSV files into application records and exports current data to CSV for backup or migration. + +Key responsibilities: +- Create: Validate required fields, generate unique IDs, persist locally, enqueue sync. +- Update: Merge changes, preserve history if needed, persist locally, enqueue sync. +- Delete: Soft-delete or remove entries, persist locally, enqueue sync. +- Bulk operations: Batch create/update/delete via CSV import or UI selection. +- Import/Export: Read/write CSV payloads for backup and cross-device migration. +- Validation: Enforce presence and format rules for company, position, salary, location, and custom fields. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) + +## Architecture Overview +The application follows a layered architecture: +- UI triggers actions in the store. +- Store updates state and invokes persistence and sync layers. +- Storage ensures offline availability. +- Sync batches and reconciles changes with the cloud backend. +- CSV utilities enable bulk operations and migration. + +```mermaid +sequenceDiagram +participant U as "User" +participant UI as "Tracker.jsx" +participant ST as "store.jsx" +participant LO as "storage.js" +participant SY as "sync.js" +participant CL as "cloud.js" +U->>UI : Submit new application +UI->>ST : createApplication(data) +ST->>LO : saveApplications(apps) +LO-->>ST : ok +ST->>SY : scheduleSync() +SY->>CL : pushChanges(batch) +CL-->>SY : ack +SY-->>ST : synced +ST-->>UI : updated state +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) + +## Detailed Component Analysis + +### Tracker Component (UI Layer) +Responsibilities: +- Renders application list and detail forms. +- Validates inputs for company name, position, salary, location, and custom fields. +- Dispatches create, update, delete actions to the store. +- Provides import/export and sync controls. + +Validation highlights: +- Required fields: company name, position. +- Optional fields: salary, location, custom fields. +- Format checks: numeric salary, non-empty strings for text fields. + +Actions exposed: +- Create: Adds a new application entry. +- Edit: Updates an existing entry by ID. +- Delete: Removes an entry by ID. +- Bulk: Imports multiple entries from CSV or applies batch updates. +- Export: Downloads current applications as CSV. +- Sync: Triggers immediate synchronization with the cloud. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Store (State Management) +Responsibilities: +- Maintains applications array and metadata. +- Exposes actions: create, update, delete, bulkImport, export, syncNow. +- Emits change events to UI and triggers persistence/sync. + +Data model: +- Each application includes identifiers, company, position, salary, location, status, notes, and custom fields. +- Timestamps track created and updated times. + +Operations: +- Create: Validates payload, assigns ID, appends to state, persists, schedules sync. +- Update: Merges fields, updates timestamp, persists, schedules sync. +- Delete: Removes by ID, persists, schedules sync. +- Bulk import: Parses CSV, validates rows, merges or creates entries, persists, schedules sync. +- Export: Serializes state to CSV. +- Sync: Invokes orchestrator to reconcile with cloud. + +**Section sources** +- [store.jsx](file://src/store.jsx) + +### Storage (Local Persistence) +Responsibilities: +- Reads/writes applications to browser storage. +- Ensures atomic writes and consistent schema. +- Supports versioning and migration helpers. + +Behavior: +- On write: serializes applications, stores under a stable key. +- On read: loads and validates schema; migrates if version changed. +- Error handling: catches serialization errors and falls back to safe defaults. + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### Sync Orchestrator +Responsibilities: +- Batches pending changes since last sync. +- Manages retry logic and conflict resolution. +- Notifies store upon completion. + +Flow: +- Collects local changes. +- Pushes to cloud in batches. +- Applies remote changes to local state. +- Resolves conflicts using timestamps or merge strategies. + +**Section sources** +- [sync.js](file://src/lib/sync.js) + +### Cloud Integration +Responsibilities: +- Authenticates user session. +- Uploads/downloads application data. +- Handles network errors and retries. + +Endpoints: +- Upload: POST batch of changes. +- Download: GET latest snapshot or incremental diff. +- Status: Returns success/failure with error codes. + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) + +### CSV Utilities (Import/Export) +Responsibilities: +- Parse CSV into structured application records. +- Export current applications to CSV. +- Map columns to fields including custom fields. + +Features: +- Header mapping and validation. +- Type coercion for salary and dates. +- Error reporting per row for invalid entries. + +**Section sources** +- [csv.js](file://src/lib/csv.js) + +### App Entry Point +Responsibilities: +- Initializes global providers and routes. +- Mounts Tracker and other pages. +- Sets up auth and entitlements that gate features like cloud sync. + +**Section sources** +- [App.jsx](file://src/App.jsx) + +## Dependency Analysis +High-level dependencies among core modules: + +```mermaid +graph LR +UI["Tracker.jsx"] --> ST["store.jsx"] +ST --> LO["storage.js"] +ST --> SY["sync.js"] +SY --> CL["cloud.js"] +UI --> CSV["csv.js"] +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) + +## Performance Considerations +- Batch operations: Prefer bulk imports over individual creates to reduce storage writes and sync overhead. +- Debounced saves: Coalesce rapid edits to minimize I/O. +- Lazy loading: Render large lists with virtualization to improve UI responsiveness. +- Conflict resolution: Use timestamp-based merging to avoid expensive reconciliation. +- Network efficiency: Compress payloads and use incremental diffs where possible. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Validation failures: Ensure required fields are present and correctly formatted. Check error messages returned by the store or UI. +- Local storage errors: Clear corrupted storage and re-import data from CSV backup. +- Sync failures: Retry after network recovery; check authentication and permissions. +- Import errors: Validate CSV headers and row formats; fix invalid rows and re-import. +- Data loss: Always export before migrations; verify schema versions during load. + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) + +## Conclusion +The tracker implements robust application management through a clear separation of concerns: UI-driven interactions, centralized state management, reliable local persistence, and resilient cloud synchronization. CSV utilities enable powerful bulk operations and seamless data migration across devices. Following the guidelines here will help you maintain data integrity, performance, and usability. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Form Validation Rules +- Company name: required, non-empty string. +- Position: required, non-empty string. +- Salary: optional, numeric value. +- Location: optional, non-empty string. +- Custom fields: optional, key-value pairs validated by schema. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) + +### Bulk Operations Examples +- Import CSV with multiple applications: map headers to fields, validate rows, then commit in a single transaction. +- Export current applications: serialize to CSV for backup or transfer. + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) + +### Data Migration Between Devices +- Export from Device A using CSV export. +- Import into Device B using CSV import. +- Enable cloud sync to keep devices in sync automatically. + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Follow-up Management System.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Follow-up Management System.md new file mode 100644 index 0000000..0005f4c --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Follow-up Management System.md @@ -0,0 +1,432 @@ +# Follow-up Management System + + +**Referenced Files in This Document** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the follow-up management system, focusing on how follow-ups are created automatically based on status changes, manual creation, scheduling and reminders, notifications, completion tracking, templates, recurring tasks, priority levels, and calendar integrations. It also provides common workflow examples and customization options to help you tailor the system to your needs. + +## Project Structure +The follow-up feature spans UI components, business logic, and data persistence: +- UI layer: Tracker component renders follow-up lists and actions. +- Business logic: followups module implements creation rules, scheduling, reminders, and completion tracking. +- Data layer: Supabase client and schema define storage for follow-ups and related entities. + +```mermaid +graph TB +subgraph "UI" +T["Tracker.jsx"] +end +subgraph "Logic" +F["followups.js"] +ST["store.jsx"] +end +subgraph "Data" +SB["supabase.js"] +DB["001_schema.sql"] +end +T --> F +T --> ST +F --> SB +SB --> DB +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Core Components +- Follow-up creation engine: Implements automatic creation based on status transitions and supports manual creation via UI or API calls. +- Scheduling and reminders: Computes next action dates, manages due windows, and triggers reminders. +- Notification system: Emits events or updates UI state when reminders are due. +- Completion tracking: Records completion timestamps and updates statuses accordingly. +- Templates and recurrence: Provides reusable follow-up definitions with optional recurrence patterns. +- Priority levels: Supports prioritization to surface urgent items first. +- Calendar integration: Exports or syncs follow-up events to external calendars. + +Key responsibilities: +- Centralize follow-up lifecycle (create, schedule, remind, complete). +- Provide a stable interface for UI and background processes. +- Persist follow-up records and metadata consistently. + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Architecture Overview +The system follows a layered architecture: +- UI Layer: Tracker component orchestrates user interactions and displays follow-up states. +- Logic Layer: followups module encapsulates business rules for creation, scheduling, reminders, and completion. +- Persistence Layer: supabase client writes/read follow-up records; schema defines tables and constraints. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "Tracker.jsx" +participant Store as "store.jsx" +participant Logic as "followups.js" +participant DB as "supabase.js" +participant Schema as "001_schema.sql" +User->>UI : "Change application status" +UI->>Store : "Dispatch status change" +Store->>Logic : "Create follow-up(s) by rule" +Logic->>DB : "Insert follow-up record" +DB-->>Schema : "Persist to database" +Logic->>UI : "Emit reminder event" +UI->>UI : "Show notification" +User->>UI : "Mark follow-up complete" +UI->>Logic : "Update completion" +Logic->>DB : "Write completion timestamp" +DB-->>Schema : "Update record" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [followups.js](file://src/lib/followups.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Automatic Follow-up Creation Based on Status Changes +- Triggers: When an application’s status transitions (e.g., from “Interview Scheduled” to “Offer Received”), the system evaluates configured rules to create one or more follow-ups. +- Rule evaluation: The logic checks current status, previous status, and any contextual flags to determine which follow-up template(s) apply. +- Idempotency: Prevents duplicate follow-ups if a matching active follow-up already exists. + +```mermaid +flowchart TD +Start(["Status Change Detected"]) --> Evaluate["Evaluate Rules
by Current and Previous Status"] +Evaluate --> HasRule{"Rule Matches?"} +HasRule --> |No| End(["No Action"]) +HasRule --> |Yes| CheckExisting["Check Existing Active Follow-ups"] +CheckExisting --> Exists{"Active Follow-up Exists?"} +Exists --> |Yes| End +Exists --> |No| Create["Create Follow-up(s)
from Template"] +Create --> Schedule["Compute Next Due Date"] +Schedule --> Persist["Persist to Database"] +Persist --> Notify["Emit Reminder Event"] +Notify --> End +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Manual Follow-up Creation +- Entry points: Users can create follow-ups directly from the Tracker UI or through programmatic calls exposed by the follow-ups module. +- Inputs: Title, description, due date/time, priority, recurrence pattern, and optional tags. +- Validation: Ensures required fields are present and dates are valid before persisting. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "Tracker.jsx" +participant Logic as "followups.js" +participant DB as "supabase.js" +User->>UI : "Open 'New Follow-up' form" +UI->>UI : "Validate inputs" +UI->>Logic : "CreateFollowUp(data)" +Logic->>DB : "Insert follow-up" +DB-->>Logic : "Record ID" +Logic-->>UI : "Return created follow-up" +UI->>UI : "Refresh list and show confirmation" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [supabase.js](file://src/lib/supabase.js) + +### Scheduling and Reminders +- Scheduling: Determines next due date based on template intervals and recurrence rules. +- Reminder windows: Supports configurable lead times (e.g., notify 24 hours before due). +- Background processing: A scheduler periodically scans upcoming due items and emits reminder events. + +```mermaid +flowchart TD +Scan["Scan Upcoming Items"] --> WindowCheck{"Within Reminder Window?"} +WindowCheck --> |No| NextItem["Next Item"] +WindowCheck --> |Yes| Emit["Emit Reminder Event"] +Emit --> UpdateUI["Update UI Notifications"] +NextItem --> Scan +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) + +### Notification Systems +- Events: The system emits reminder events that UI components can subscribe to. +- Delivery: Notifications appear in-app; future extensions may support email or push notifications. +- State synchronization: UI reflects real-time updates when new reminders are emitted. + +```mermaid +sequenceDiagram +participant Scheduler as "Scheduler" +participant Logic as "followups.js" +participant Store as "store.jsx" +participant UI as "Tracker.jsx" +Scheduler->>Logic : "OnDue(followUpId)" +Logic->>Store : "Dispatch reminder update" +Store-->>UI : "State updated" +UI->>UI : "Render notification badge" +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Completion Tracking +- Actions: Users mark follow-ups as completed, optionally adding notes or outcomes. +- Timestamps: Completion time is recorded for analytics and audit trails. +- Status updates: Completed follow-ups may trigger downstream status changes or close related tasks. + +```mermaid +flowchart TD +Start(["Mark Complete"]) --> Validate["Validate Completion Inputs"] +Validate --> Valid{"Valid?"} +Valid --> |No| ShowError["Show Error Message"] +Valid --> |Yes| Persist["Persist Completion Timestamp"] +Persist --> UpdateState["Update Local State"] +UpdateState --> Notify["Notify UI and Integrations"] +Notify --> End(["Done"]) +ShowError --> End +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Follow-up Templates +- Purpose: Reusable definitions for common follow-up types (e.g., “Post-interview thank-you,” “Offer negotiation”). +- Attributes: Default title, description, due offset, recurrence, priority, and tags. +- Customization: Users can override defaults at creation time. + +```mermaid +classDiagram +class FollowUpTemplate { ++string id ++string name ++string description ++number dueOffsetDays ++boolean recurring ++string recurrencePattern ++string priority ++string[] tags +} +class FollowUp { ++string id ++string templateId ++string title ++string description ++datetime dueDate ++boolean recurring ++string recurrencePattern ++string priority ++string status ++datetime createdAt ++datetime completedAt ++string[] tags +} +FollowUp --> FollowUpTemplate : "uses" +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Recurring Tasks +- Patterns: Support for daily, weekly, monthly, or custom intervals. +- Generation: On completion, the system schedules the next instance according to the recurrence pattern. +- Boundaries: Optional end date or occurrence count to limit recurrence. + +```mermaid +flowchart TD +Complete["Complete Follow-up"] --> Pattern["Read Recurrence Pattern"] +Pattern --> Compute["Compute Next Due Date"] +Compute --> LimitCheck{"Reached End Condition?"} +LimitCheck --> |Yes| Close["Close Follow-up"] +LimitCheck --> |No| CreateNext["Create Next Instance"] +CreateNext --> Persist["Persist New Follow-up"] +Close --> End(["Done"]) +Persist --> End +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) + +### Priority Levels +- Levels: Low, Normal, High, Urgent. +- Sorting: Higher priority items surface earlier in lists and receive earlier reminders. +- Escalation: Optionally escalate overdue high-priority items. + +```mermaid +flowchart TD +Assign["Assign Priority"] --> Sort["Sort by Priority and Due Date"] +Sort --> Display["Display in UI"] +Display --> Remind["Apply Reminder Windows"] +Remind --> End(["Done"]) +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) + +### Integration with Calendar Systems +- Export: Generate calendar entries (.ics) for follow-ups. +- Sync: Push follow-up events to external calendars (future extension). +- Two-way sync: Update follow-up status when calendar events are marked done (future extension). + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx" +participant Logic as "followups.js" +participant Cal as "Calendar Service" +UI->>Logic : "Export to Calendar" +Logic->>Cal : "Generate .ics / Sync Event" +Cal-->>Logic : "Success/Failure" +Logic-->>UI : "Show result" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) + +## Dependency Analysis +The follow-up system depends on UI state management and persistent storage: +- Tracker.jsx interacts with store.jsx to reflect follow-up state. +- followups.js coordinates creation, scheduling, and completion logic. +- supabase.js persists data using the schema defined in migrations. + +```mermaid +graph TB +T["Tracker.jsx"] --> S["store.jsx"] +T --> F["followups.js"] +F --> SB["supabase.js"] +SB --> M["001_schema.sql"] +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [followups.js](file://src/lib/followups.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [followups.js](file://src/lib/followups.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Performance Considerations +- Batch operations: Group multiple follow-up creations during bulk status changes to reduce database round-trips. +- Indexing: Ensure database indexes on dueDate, status, and templateId for efficient queries. +- Debounce UI updates: Coalesce frequent reminder emissions to avoid excessive re-renders. +- Lazy loading: Load only necessary follow-up fields initially; fetch details on demand. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Duplicate follow-ups: Verify idempotency checks prevent duplicates when creating from templates. +- Missed reminders: Confirm scheduler runs regularly and reminder windows are correctly computed. +- Incomplete persistence: Check database write operations and error handling paths. +- UI not updating: Ensure store dispatches and subscribers are wired correctly. + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +The follow-up management system provides robust automation for creating, scheduling, reminding, and completing follow-ups. With templates, recurrence, priorities, and calendar integrations, it supports diverse workflows while remaining customizable and extensible. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Common Workflows +- Post-interview follow-up: After marking an interview as completed, automatically create a thank-you note follow-up due within 24 hours. +- Offer negotiation: When offer received status is set, create a series of follow-ups for review, counter-offer, and acceptance steps. +- Weekly check-ins: Recurring weekly follow-ups assigned to managers for candidate progress reviews. + +[No sources needed since this section doesn't analyze specific files] + +### Customization Options +- Add new templates: Define new follow-up templates with default attributes and recurrence patterns. +- Adjust reminder windows: Configure lead times per template or globally. +- Extend priority levels: Introduce additional categories and escalation rules. +- Calendar providers: Implement sync adapters for Google Calendar, Outlook, or Apple Calendar. + +[No sources needed since this section doesn't analyze specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Job Application Tracker.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Job Application Tracker.md new file mode 100644 index 0000000..2dd70c7 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Job Application Tracker.md @@ -0,0 +1,437 @@ +# Job Application Tracker + + +**Referenced Files in This Document** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +The Job Application Tracker provides a dashboard for managing job applications, tracking statuses, and automating follow-ups. It supports adding, editing, and organizing applications; visualizing statistics; suggesting next actions; and integrating with AI analysis and offer comparison features. Users can configure custom fields, export/import data, and share their tracker securely. + +## Project Structure +The tracker is implemented as a React application with modular libraries for analytics, automation, and integrations: +- UI layer: Dashboard and forms are rendered by the Tracker component. +- Logic layer: Follow-up scheduling, next action suggestions, scoring, red flags, and statistics are provided by dedicated modules. +- Data layer: Local storage, Supabase sync, CSV import/export, and sharing utilities manage persistence and portability. +- Integrations: AI proxy and billing/entitlements enable advanced features like AI analysis and premium capabilities. + +```mermaid +graph TB +subgraph "UI" +T["Tracker.jsx"] +A["App.jsx"] +end +subgraph "Logic" +F["followups.js"] +N["nextaction.js"] +S["stats.js"] +SC["scoring.js"] +RF["redflags.js"] +AN["analyze.js"] +AI["ai.js"] +end +subgraph "Data & Sync" +ST["store.jsx"] +SB["supabase.js"] +SY["sync.js"] +CL["cloud.js"] +CSV["csv.js"] +SH["share.js"] +end +subgraph "Integrations" +ENT["entitlement.js"] +PR["pricing.js"] +BI["billing.js"] +end +A --> T +T --> F +T --> N +T --> S +T --> SC +T --> RF +T --> AN +T --> AI +T --> ST +ST --> SB +ST --> SY +SY --> CL +T --> CSV +T --> SH +T --> ENT +ENT --> PR +ENT --> BI +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) + +## Core Components +- Tracker dashboard: Central interface to add, edit, filter, sort, and visualize applications. +- Follow-up automation: Schedules reminders based on last contact or status changes. +- Next action engine: Suggests actionable steps derived from application state and rules. +- Statistics and analytics: Aggregates counts, conversion rates, time-to-status, and funnel metrics. +- Scoring and red flags: Computes composite scores and highlights potential risks. +- AI analysis integration: Sends anonymized application details to an AI proxy for insights. +- Data management: Import/export via CSV, secure sharing links, and cloud sync via Supabase. +- Entitlements and billing: Gates premium features (e.g., AI analysis) behind subscription checks. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [analyze.js](file://src/lib/analyze.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +## Architecture Overview +The tracker follows a layered architecture: +- Presentation: React components render dashboards and forms. +- Domain logic: Pure functions compute follow-ups, next actions, stats, scores, and flags. +- Data access: Store coordinates local state, Supabase client, and sync routines. +- External services: AI proxy, billing endpoints, and entitlement checks. + +```mermaid +sequenceDiagram +participant U as "User" +participant UI as "Tracker.jsx" +participant ST as "store.jsx" +participant DB as "supabase.js" +participant SY as "sync.js" +participant CL as "cloud.js" +participant AI as "ai.js" +participant ENT as "entitlement.js" +U->>UI : Add/Edit Application +UI->>ST : Update local state +ST->>DB : Persist record +ST->>SY : Trigger sync +SY->>CL : Upload/Download changes +U->>UI : Request AI Analysis +UI->>ENT : Check entitlement +ENT-->>UI : Allowed/Denied +UI->>AI : Send payload +AI-->>UI : Insights +UI->>ST : Save insights +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [ai.js](file://src/lib/ai.js) +- [entitlement.js](file://src/lib/entitlement.js) + +## Detailed Component Analysis + +### Tracker Dashboard Interface +Responsibilities: +- Display list/grid view of applications with filters and sorting. +- Provide forms to add/edit applications and update statuses. +- Render statistics panels and charts. +- Surface next action suggestions and follow-up tasks. +- Integrate AI analysis and offer comparison entry points. + +Key interactions: +- CRUD operations flow through store.jsx to persist locally and optionally sync to Supabase. +- Analytics computed by stats.js feed visualization widgets. +- Follow-ups and next actions computed by followups.js and nextaction.js respectively. + +Common usage patterns: +- Bulk import via CSV, then refine entries using inline edits. +- Filter by company, role, status, or tags; sort by date or score. +- Use “Next Action” panel to prioritize daily tasks. +- Toggle custom fields to tailor the schema to your workflow. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [csv.js](file://src/lib/csv.js) + +### Application Management Workflows +Workflows: +- Add application: Fill form fields, save to local store, optional sync. +- Edit application: Open detail view, modify fields/status, recompute dependent metrics. +- Organize: Apply tags, categories, and custom fields; use filters and views. +- Import/Export: CSV import populates records; export shares or archives data. +- Share: Generate shareable link with read-only or limited write permissions. + +Data flow: +- UI updates trigger store mutations. +- Store persists to local storage and triggers sync if enabled. +- CSV and share utilities operate on normalized records. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) + +### Status Tracking System +Status lifecycle: +- Typical stages include Applied, Screening, Interview, Offer, Rejected, Archived. +- Transitions update timestamps and influence analytics (time-in-stage, conversion). +- Red flags may be raised when certain conditions are met (e.g., long idle periods). + +Automation: +- Follow-ups scheduled after status changes or last contact dates. +- Next action suggestions propose concrete steps (e.g., “Send thank-you note,” “Follow up with recruiter”). + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) + +### Follow-up Automation +Rules: +- Schedule reminders based on days since last contact or status change. +- Escalate overdue follow-ups and group by priority. +- Allow manual overrides and snoozing. + +Integration: +- UI surfaces upcoming tasks and allows quick completion. +- Completion updates timestamps and recalculates next actions. + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Statistics and Analytics +Metrics: +- Counts by status, source, and tags. +- Conversion rates across pipeline stages. +- Time-to-status averages and percentiles. +- Funnel visualization showing drop-offs. + +Computation: +- stats.js aggregates records into summary objects. +- UI renders charts and KPI cards. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Next Action Suggestions +Algorithm: +- Analyzes application state, status, and history. +- Applies rule-based heuristics to recommend immediate next steps. +- Prioritizes by urgency and impact. + +Output: +- Action items surfaced in the dashboard and task list. +- Actions can be marked done, which updates downstream metrics. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Custom Fields Configuration +Capabilities: +- Define additional fields per application (text, number, date, select). +- Include custom fields in import/export and filtering. +- Persist custom schemas alongside records. + +Usage: +- Configure once and apply across all applications. +- Use in reports and views for tailored insights. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [csv.js](file://src/lib/csv.js) + +### Integration with AI Analysis and Offer Comparison +AI Analysis: +- Optional feature gated by entitlements. +- Sends anonymized application context to AI proxy for feedback. +- Results stored with the application for review. + +Offer Comparison: +- Compare multiple offers side-by-side using standardized criteria. +- Visualize trade-offs and compute weighted scores. + +**Section sources** +- [ai.js](file://src/lib/ai.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Data Visualization Features +Visualizations: +- Pipeline funnel chart. +- Status distribution pie/bar charts. +- Trend lines for weekly/monthly activity. +- Score and red flag heatmaps. + +Implementation: +- Data prepared by stats.js and passed to chart components within Tracker.jsx. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Dependency Analysis +High-level dependencies: +- Tracker depends on domain logic modules for computation and rendering. +- Store centralizes state and orchestrates persistence and sync. +- External integrations are isolated behind clear interfaces. + +```mermaid +graph LR +T["Tracker.jsx"] --> F["followups.js"] +T --> N["nextaction.js"] +T --> S["stats.js"] +T --> SC["scoring.js"] +T --> RF["redflags.js"] +T --> AN["analyze.js"] +T --> AI["ai.js"] +T --> ST["store.jsx"] +ST --> SB["supabase.js"] +ST --> SY["sync.js"] +SY --> CL["cloud.js"] +T --> CSV["csv.js"] +T --> SH["share.js"] +T --> ENT["entitlement.js"] +ENT --> PR["pricing.js"] +ENT --> BI["billing.js"] +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [analyze.js](file://src/lib/analyze.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) + +## Performance Considerations +- Prefer memoization and selective re-renders in the dashboard to handle large datasets. +- Batch updates when importing CSV to avoid excessive re-renders. +- Defer heavy computations (statistics, AI calls) until needed or offload to background tasks. +- Use pagination or virtualization for long lists. +- Cache frequently accessed analytics results and invalidate on data changes. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Sync failures: Verify network connectivity and Supabase credentials; retry sync routine. +- Missing follow-ups: Ensure last contact and status timestamps are set; check rule thresholds. +- Incorrect stats: Validate data completeness and date formats; recompute summaries. +- AI analysis blocked: Confirm entitlements and subscription status; review pricing/billing integration. +- CSV import errors: Inspect column mappings and required fields; normalize values before import. + +Operational tips: +- Use share links to validate read-only access without altering data. +- Export snapshots before major schema changes or bulk edits. +- Review red flags to identify stale or risky applications needing attention. + +**Section sources** +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [pricing.js](file://src/lib/pricing.js) +- [billing.js](file://src/lib/billing.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [redflags.js](file://src/lib/redflags.js) + +## Conclusion +The Job Application Tracker combines a flexible dashboard with robust automation and analytics. It streamlines application management, keeps users proactive with follow-ups and next actions, and provides actionable insights through statistics and optional AI analysis. With customizable fields, import/export, and secure sharing, it adapts to diverse workflows while maintaining performance and reliability. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Example Usage Patterns +- Weekly review: Filter by “Interview” and “Offer,” mark completed follow-ups, and review next actions. +- Campaign tracking: Tag applications by source and campaign; analyze conversion by channel. +- Offer negotiation: Use offer comparison to weigh compensation, benefits, and growth opportunities. + +[No sources needed since this section doesn't analyze specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Next Action Suggestions.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Next Action Suggestions.md new file mode 100644 index 0000000..643166f --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Next Action Suggestions.md @@ -0,0 +1,469 @@ +# Next Action Suggestions + + +**Referenced Files in This Document** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the next action suggestion system that analyzes application states to generate intelligent recommendations, prioritizes actions based on context and risk, and provides user feedback mechanisms. It covers the rule engine behind suggestions, customization options, integration points with the UI, and examples of common scenarios where suggestions add value. The goal is to help both technical and non-technical users understand how the system works and how to refine its behavior. + +## Project Structure +The next action suggestion system is implemented primarily in the lib layer as a set of focused modules: +- State analysis and scoring +- Risk detection (red flags) +- Follow-up and missing data detection +- Statistics and prompts for contextual guidance +- AI-assisted refinement when enabled +- UI integration via components and store + +```mermaid +graph TB +subgraph "Lib Layer" +A["analyze.js"] +B["scoring.js"] +C["redflags.js"] +D["followups.js"] +E["missing.js"] +F["stats.js"] +G["prompt.js"] +H["ai.js"] +I["nextaction.js"] +end +subgraph "UI Layer" +J["AiAssistant.jsx"] +K["Tracker.jsx"] +L["store.jsx"] +end +A --> B +A --> C +A --> D +A --> E +A --> F +A --> G +A --> H +B --> I +C --> I +D --> I +E --> I +F --> I +G --> I +H --> I +I --> L +L --> J +L --> K +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Core Components +- Rule Engine Orchestrator: Coordinates analysis, scoring, red flag detection, follow-ups, missing data checks, statistics, prompts, and optional AI assistance to produce ranked next actions. +- Analyzer: Extracts relevant state features from the current application snapshot. +- Scorer: Computes numeric scores for candidate actions using weighted criteria. +- Red Flags Detector: Identifies high-risk conditions that should elevate priority. +- Follow-ups and Missing Data: Surfaces incomplete or overdue items requiring attention. +- Stats and Prompts: Provides contextual nudges and summary insights. +- AI Assistant: Optionally augments suggestions with AI-generated refinements. +- Store Integration: Exposes computed suggestions to UI components and persists user preferences. + +Key responsibilities and interactions are detailed in the architecture and component sections below. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview +The system follows a modular pipeline: +- Input: Current application state snapshot +- Processing: Analyze -> Score -> Detect Risks -> Identify Follow-ups/Missing -> Compute Stats/Prompts -> Optional AI Refinement +- Output: Prioritized list of next actions with metadata and rationale + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx / AiAssistant.jsx" +participant Store as "store.jsx" +participant NA as "nextaction.js" +participant AN as "analyze.js" +participant SC as "scoring.js" +participant RF as "redflags.js" +participant FU as "followups.js" +participant MI as "missing.js" +participant ST as "stats.js" +participant PR as "prompt.js" +participant AI as "ai.js" +UI->>Store : Request suggestions +Store->>NA : BuildContext(state) +NA->>AN : Analyze(state) +AN-->>NA : Features +NA->>SC : Score(features) +SC-->>NA : Scores +NA->>RF : CheckRedFlags(features) +RF-->>NA : Flags +NA->>FU : GetFollowUps(features) +FU-->>NA : FollowUps +NA->>MI : GetMissingData(features) +MI-->>NA : Missing +NA->>ST : ComputeStats(features) +ST-->>NA : Stats +NA->>PR : GeneratePrompts(stats) +PR-->>NA : Prompts +NA->>AI : OptionalRefine(suggestions, context) +AI-->>NA : RefinedSuggestions +NA-->>Store : RankedActions +Store-->>UI : DisplaySuggestions +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Detailed Component Analysis + +### Rule Engine Orchestrator (nextaction.js) +Responsibilities: +- Aggregates inputs from analyzer, scorer, red flags, follow-ups, missing data, stats, prompts, and optional AI. +- Applies prioritization logic combining scores, risk flags, recency, and completeness. +- Produces a final ranked list of actionable items with explanations and metadata. + +Prioritization algorithm highlights: +- Base score derived from scoring module +- Risk multiplier or additive boost for red flags +- Penalty for low completion or missing required fields +- Contextual weighting from stats and prompts +- Optional AI adjustments for personalization + +Customization hooks: +- Weight tuning for score components +- Thresholds for red flag severity +- Prompt templates and stats thresholds +- AI enablement and prompt parameters + +Integration: +- Consumed by store.jsx to expose suggestions to UI +- Supports re-computation on state changes + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) + +#### Class Diagram (Conceptual Mapping) +```mermaid +classDiagram +class NextActionEngine { ++buildContext(state) ++computeSuggestions() ++applyWeights() ++applyRiskBoost() ++applyCompletionPenalty() ++applyPromptWeighting() ++optionalAIFixup() ++rankAndReturn() +} +class Analyzer { ++extractFeatures(state) +} +class Scorer { ++scoreFeatures(features) +} +class RedFlags { ++detect(flags, features) +} +class FollowUps { ++listPending(features) +} +class MissingData { ++findMissing(features) +} +class Stats { ++summarize(features) +} +class Prompts { ++generate(stats) +} +class AIAssistant { ++refine(suggestions, context) +} +NextActionEngine --> Analyzer : "uses" +NextActionEngine --> Scorer : "uses" +NextActionEngine --> RedFlags : "uses" +NextActionEngine --> FollowUps : "uses" +NextActionEngine --> MissingData : "uses" +NextActionEngine --> Stats : "uses" +NextActionEngine --> Prompts : "uses" +NextActionEngine --> AIAssistant : "optional" +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +### Analyzer (analyze.js) +Responsibilities: +- Normalizes raw application state into structured features used downstream. +- Derives temporal signals (recency), completeness indicators, and categorical tags. + +Complexity considerations: +- Typically O(n) over feature dimensions; ensure minimal allocations during frequent updates. + +Optimization opportunities: +- Memoize expensive computations keyed by stable state snapshots. +- Incremental updates when only subsets of state change. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Scorer (scoring.js) +Responsibilities: +- Computes numeric scores per candidate action based on weighted criteria. +- Supports configurable weights and normalization. + +Algorithmic notes: +- Linear combination of normalized features; consider robust scaling to avoid dominance by outliers. +- Tie-breaking rules based on recency or category importance. + +Customization: +- Adjust weights for different workflows or user segments. +- Introduce domain-specific multipliers. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) + +### Red Flags (redflags.js) +Responsibilities: +- Detects high-risk conditions that should elevate action priority. +- Returns flags with severity levels and suggested mitigations. + +Design patterns: +- Rule-based detection with clear condition sets. +- Extensible registry of new red flag detectors. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) + +### Follow-ups (followups.js) +Responsibilities: +- Identifies pending or overdue follow-up tasks. +- Incorporates deadlines and recurrence patterns. + +Edge cases: +- Grace periods and snoozed items. +- Handling ambiguous due dates. + +**Section sources** +- [followups.js](file://src/lib/followups.js) + +### Missing Data (missing.js) +Responsibilities: +- Finds incomplete or missing required fields for an action. +- Suggests specific data collection steps. + +Validation strategy: +- Schema-driven checks with clear error messages. +- Grouped suggestions to reduce cognitive load. + +**Section sources** +- [missing.js](file://src/lib/missing.js) + +### Stats and Prompts (stats.js, prompt.js) +Responsibilities: +- Summarizes recent activity and trends. +- Generates contextual prompts to guide user focus. + +Personalization: +- Tailor prompts based on user history and preferences. +- Avoid repetition and fatigue through deduplication. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) + +### AI Assistance (ai.js) +Responsibilities: +- Optionally refines suggestions using AI models. +- Respects privacy and performance constraints. + +Controls: +- Enable/disable toggle. +- Temperature and length controls for generated content. +- Fallback to deterministic rules if AI fails. + +**Section sources** +- [ai.js](file://src/lib/ai.js) + +### UI Integration (store.jsx, Tracker.jsx, AiAssistant.jsx) +Responsibilities: +- store.jsx exposes computed suggestions and user preferences. +- Tracker.jsx displays prioritized actions and handles user interactions. +- AiAssistant.jsx integrates AI-powered refinements and feedback loops. + +User feedback mechanisms: +- Dismiss, snooze, mark complete, and “not helpful” feedback. +- Persist preferences to tune future suggestions. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Dependency Analysis +The orchestrator depends on multiple specialized modules. Coupling is minimized by clear interfaces and composition. + +```mermaid +graph LR +NA["nextaction.js"] --> AN["analyze.js"] +NA --> SC["scoring.js"] +NA --> RF["redflags.js"] +NA --> FU["followups.js"] +NA --> MI["missing.js"] +NA --> ST["stats.js"] +NA --> PR["prompt.js"] +NA --> AI["ai.js"] +STX["store.jsx"] --> NA +UI1["Tracker.jsx"] --> STX +UI2["AiAssistant.jsx"] --> STX +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [missing.js](file://src/lib/missing.js) +- [stats.js](file://src/lib/stats.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Performance Considerations +- Prefer memoization for analyzer outputs keyed by immutable snapshots. +- Batch recomputations when multiple state slices update simultaneously. +- Limit AI calls to necessary contexts; cache results when safe. +- Use incremental updates for large datasets to avoid full re-scoring. +- Debounce rapid UI interactions to prevent thrashing. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Stale suggestions after state changes: Ensure store subscribes to relevant state slices and triggers recomputation. +- Overly aggressive red flags: Tune severity thresholds and review rule conditions. +- Repetitive prompts: Implement deduplication and decay strategies. +- AI failures: Fall back to deterministic rules and log errors for diagnostics. +- Performance regressions: Profile analyzer and scorer hot paths; introduce caching. + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) + +## Conclusion +The next action suggestion system combines deterministic rules with optional AI enhancements to deliver context-aware, prioritized recommendations. Its modular design enables customization, extensibility, and smooth integration with the UI. By tuning weights, thresholds, and prompts—and leveraging user feedback—the system can adapt to evolving workflows while maintaining clarity and performance. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Common Scenarios and Value Examples +- Onboarding flow: Suggest completing missing profile fields before proceeding. +- Risk mitigation: Elevate actions flagged by red flags to top priority. +- Deadline management: Surface overdue follow-ups with clear next steps. +- Personalization: Learn from dismiss/snooze/complete feedback to refine future suggestions. + +[No sources needed since this section doesn't analyze specific source files] + +### Customization Options +- Weights and thresholds in scoring and red flags. +- Prompt templates and frequency controls. +- AI enablement and generation parameters. +- Persistence of user preferences for long-term adaptation. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [store.jsx](file://src/store.jsx) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Follow-up Automation.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Follow-up Automation.md new file mode 100644 index 0000000..5b128f5 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Follow-up Automation.md @@ -0,0 +1,371 @@ +# Follow-up Automation + + +**Referenced Files in This Document** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [settings.jsx](file://src/components/Settings.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the follow-up automation system that schedules and manages application follow-ups based on status changes, custom rules, and reminders. It covers how timelines are tracked, next actions are suggested, and notifications are managed. It also documents configuration options for intervals, escalation rules, and integration points with external calendar systems. + +The system is implemented primarily as client-side logic with optional cloud synchronization and Supabase-backed persistence. + +## Project Structure +The follow-up automation spans several modules: +- Core scheduling and rule engine: src/lib/followups.js +- Next action suggestion engine: src/lib/nextaction.js +- UI components for tracking and settings: src/components/Tracker.jsx, src/components/Settings.jsx +- State management and persistence: src/store.jsx, src/lib/supabase.js, src/lib/cloud.js, src/lib/sync.js + +```mermaid +graph TB +subgraph "UI" +Tracker["Tracker.jsx"] +Settings["Settings.jsx"] +end +subgraph "Core Logic" +Followups["followups.js"] +NextAction["nextaction.js"] +end +subgraph "Persistence & Sync" +Store["store.jsx"] +Supabase["supabase.js"] +Cloud["cloud.js"] +Sync["sync.js"] +end +Tracker --> Followups +Tracker --> NextAction +Settings --> Followups +Followups --> Store +NextAction --> Store +Store --> Supabase +Store --> Cloud +Sync --> Store +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +## Core Components +- Follow-up scheduler and rule engine (followups.js): Computes next follow-up dates from status transitions, applies custom intervals, and enforces escalation policies. +- Next action suggestion engine (nextaction.js): Derives recommended next steps based on current state, history, and configured rules. +- Tracking UI (Tracker.jsx): Displays timelines, upcoming follow-ups, and allows manual adjustments. +- Settings UI (Settings.jsx): Configures default intervals, escalation thresholds, and notification preferences. +- Persistence and sync (store.jsx, supabase.js, cloud.js, sync.js): Manages local state, persists to Supabase, and optionally syncs across devices or services. + +Key responsibilities: +- Automatic scheduling triggered by status changes +- Customizable follow-up intervals per stage/status +- Escalation rules when deadlines approach or pass +- Reminder generation and delivery hooks +- Next action suggestions derived from context + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +## Architecture Overview +The follow-up automation follows a layered architecture: +- Presentation layer: Tracker and Settings render timelines, upcoming tasks, and configuration. +- Business logic layer: followups.js computes schedules; nextaction.js suggests next steps. +- Data layer: store.jsx coordinates state; supabase.js persists records; cloud.js and sync.js handle optional remote operations. + +```mermaid +sequenceDiagram +participant UI as "Tracker.jsx" +participant Rules as "followups.js" +participant Actions as "nextaction.js" +participant Store as "store.jsx" +participant DB as "supabase.js" +participant Cloud as "cloud.js" +participant Sync as "sync.js" +UI->>Store : Load application timeline +Store->>DB : Read persisted records +DB-->>Store : Timeline data +Store-->>UI : Render timeline +UI->>Rules : Apply status change +Rules->>Store : Update schedule and reminders +Rules->>Actions : Request next action suggestions +Actions-->>Rules : Suggested next steps +Rules->>Cloud : Optional push to cloud +Cloud-->>Rules : Acknowledgement +Sync->>Store : Sync latest state +Store-->>UI : Refresh view +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +## Detailed Component Analysis + +### Follow-up Scheduler and Rule Engine +Responsibilities: +- Compute next follow-up date based on current status and configured intervals +- Enforce escalation rules when approaching or missing deadlines +- Generate reminder events and update timeline entries +- Support custom rules per stage/status + +Operational flow: +- On status change, compute delta using configured interval +- If escalation threshold reached, mark as escalated and adjust priority +- Persist updated schedule and notify UI via store updates + +```mermaid +flowchart TD +Start(["Status Change Event"]) --> Validate["Validate new status and timestamps"] +Validate --> LookupInterval["Lookup configured interval for status"] +LookupInterval --> ComputeNext["Compute next follow-up timestamp"] +ComputeNext --> CheckEscalation{"Approaching or past deadline?"} +CheckEscalation --> |Yes| Escalate["Apply escalation rules
and increase priority"] +CheckEscalation --> |No| KeepPriority["Maintain current priority"] +Escalate --> UpdateSchedule["Update schedule and reminders"] +KeepPriority --> UpdateSchedule +UpdateSchedule --> Persist["Persist to store and database"] +Persist --> Notify["Notify UI and optional cloud sync"] +Notify --> End(["Done"]) +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) + +### Next Action Suggestion Engine +Responsibilities: +- Analyze current timeline, status history, and configured rules +- Produce actionable next steps (e.g., “Send reminder,” “Request additional info,” “Close”) +- Incorporate user-defined preferences and historical patterns + +Integration: +- Called by the scheduler after updates to refine recommendations +- Exposed to UI for display and quick actions + +```mermaid +classDiagram +class NextActionEngine { ++analyze(context) Array ++suggestNextSteps(timeline, rules) Array +-evaluatePatterns(history) Array +-applyPreferences(userPrefs) Array +} +class TimelineContext { ++statusHistory ++timestamps ++rules +} +NextActionEngine --> TimelineContext : "consumes" +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) + +### Tracking UI and Settings +Tracking UI: +- Displays timeline, upcoming follow-ups, and escalations +- Allows manual overrides and quick actions +- Subscribes to store updates for real-time refresh + +Settings UI: +- Configures default intervals per status +- Defines escalation thresholds and priorities +- Toggles reminder channels and cloud sync + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "Tracker.jsx / Settings.jsx" +participant Store as "store.jsx" +participant Rules as "followups.js" +participant Actions as "nextaction.js" +User->>UI : Adjust settings +UI->>Store : Save preferences +Store-->>UI : Confirm saved +User->>UI : Change application status +UI->>Rules : Trigger scheduling +Rules->>Actions : Request suggestions +Actions-->>Rules : Suggestions +Rules->>Store : Update timeline and reminders +Store-->>UI : Render updated view +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) + +### Persistence and Sync +Responsibilities: +- Local state management and reactive updates +- Persisting timeline, schedules, and settings to Supabase +- Optional cloud sync and cross-device consistency + +```mermaid +graph TB +Store["store.jsx"] --> Supabase["supabase.js"] +Store --> Cloud["cloud.js"] +Sync["sync.js"] --> Store +UI["Tracker.jsx / Settings.jsx"] --> Store +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +## Dependency Analysis +The follow-up system exhibits clear separation between UI, business logic, and data layers. The core dependencies are: +- Tracker.jsx depends on followups.js and nextaction.js for scheduling and suggestions +- Settings.jsx depends on followups.js for applying configuration changes +- followups.js depends on store.jsx for state updates and supabase.js for persistence +- nextaction.js depends on store.jsx for reading timeline context +- sync.js orchestrates background synchronization with cloud and database + +```mermaid +graph LR +Tracker["Tracker.jsx"] --> Followups["followups.js"] +Tracker --> NextAction["nextaction.js"] +Settings["Settings.jsx"] --> Followups +Followups --> Store["store.jsx"] +NextAction --> Store +Store --> Supabase["supabase.js"] +Store --> Cloud["cloud.js"] +Sync["sync.js"] --> Store +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +## Performance Considerations +- Batch updates: Group multiple status changes before recomputing schedules to reduce redundant calculations. +- Lazy evaluation: Defer next action suggestions until they are needed by the UI. +- Efficient persistence: Use minimal writes to Supabase; coalesce updates and leverage optimistic UI where appropriate. +- Caching: Cache computed intervals and escalation decisions to avoid repeated computations. +- Background sync: Throttle sync operations to prevent network contention and prioritize critical updates. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Schedule not updating after status change: Verify that the status change triggers the scheduler and that store updates propagate to the UI. +- Missing reminders: Check escalation thresholds and configured intervals; ensure reminders are persisted and synced. +- Incorrect next action suggestions: Review input context and rule configurations; validate timeline history integrity. +- Sync conflicts: Inspect sync logs and resolve conflicts by prioritizing the most recent authoritative source. + +**Section sources** +- [followups.js](file://src/lib/followups.js) +- [followups.test.js](file://src/lib/followups.test.js) +- [sync.js](file://src/lib/sync.js) + +## Conclusion +The follow-up automation system provides robust scheduling, customizable rules, and intelligent next action suggestions. Its layered architecture ensures maintainability and scalability, while persistence and sync features support reliable operation across devices. Proper configuration of intervals and escalation rules enables effective timeline management and timely reminders. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Configuration Options +- Default intervals per status: Define time deltas for each stage to compute next follow-ups. +- Escalation thresholds: Set conditions under which items are marked escalated and priorities increased. +- Reminder channels: Toggle notifications and integrate with external calendars if supported. +- Sync preferences: Enable/disable cloud sync and conflict resolution strategies. + +**Section sources** +- [Settings.jsx](file://src/components/Settings.jsx) +- [followups.js](file://src/lib/followups.js) + +### Integration Points +- External calendar systems: Export scheduled follow-ups and reminders to calendar providers via available integrations. +- Notification services: Hook into platform notification APIs for reminders and escalations. +- Cloud storage: Persist timeline and settings to Supabase and synchronize across devices. + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [sync.js](file://src/lib/sync.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Status Pipeline Management.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Status Pipeline Management.md new file mode 100644 index 0000000..3e2dc64 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Status Pipeline Management.md @@ -0,0 +1,283 @@ +# Status Pipeline Management + + +**Referenced Files in This Document** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the status pipeline management system used to track application lifecycle stages. It covers predefined statuses, custom status creation and configuration, transition rules and validation constraints, visual indicators (including color coding and progress tracking), and practical examples for changing statuses, performing bulk updates, and integrating with the tracker interface. The goal is to help both technical and non-technical users understand how statuses are modeled, persisted, and presented across the application. + +## Project Structure +The status pipeline spans UI components, state management, and database schema: +- Tracker UI component renders the pipeline view and user interactions for status changes. +- Store module centralizes state, persistence, and operations related to applications and their statuses. +- Supabase client provides data access and synchronization. +- Database migration defines the core schema for applications and their status fields. + +```mermaid +graph TB +subgraph "Frontend" +T["Tracker.jsx"] +S["store.jsx"] +C["components (e.g., Toast.jsx)"] +end +subgraph "Data Layer" +DB["Supabase Client (supabase.js)"] +SCHEMA["DB Schema (001_schema.sql)"] +end +T --> S +S --> DB +DB --> SCHEMA +T --> C +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Core Components +- Tracker UI: Presents the list or board of applications, shows current status, and exposes controls to change status. It also reflects progress and highlights based on status values. +- Store: Holds application records and status metadata, enforces transition rules, persists changes, and coordinates with the Supabase client. +- Supabase Client: Provides typed queries and mutations to read/write application records and status fields. +- Schema: Defines the table structure for applications and status-related columns, including any constraints and indexes. + +Key responsibilities: +- Predefined workflow states and transitions +- Custom status creation and configuration +- Validation and constraints for transitions +- Visual indicators (colors, progress) +- Bulk update operations +- Integration points with the tracker UI + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Architecture Overview +The status pipeline follows a layered architecture: +- Presentation layer (Tracker) handles user input and displays status visuals. +- State layer (Store) encapsulates business logic for transitions and persistence. +- Data layer (Supabase + Schema) persists application records and status fields. + +```mermaid +sequenceDiagram +participant User as "User" +participant Tracker as "Tracker.jsx" +participant Store as "store.jsx" +participant Supa as "supabase.js" +participant DB as "Schema (001_schema.sql)" +User->>Tracker : "Select application and new status" +Tracker->>Store : "Request status change" +Store->>Store : "Validate transition rules" +alt "Valid" +Store->>Supa : "Update application status" +Supa->>DB : "Persist change" +DB-->>Supa : "Success" +Supa-->>Store : "Updated record" +Store-->>Tracker : "Notify UI to refresh" +Tracker-->>User : "Show updated status and visuals" +else "Invalid" +Store-->>Tracker : "Reject with reason" +Tracker-->>User : "Show error feedback" +end +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Predefined Status Workflow +The pipeline includes standard stages such as applied, screening, interview, offer, and rejected. These represent the canonical flow from initial submission through final decision. The store should define these states and the allowed transitions between them. For example, an application typically progresses forward through these stages and may be moved back only under specific conditions defined by transition rules. + +- Typical progression: applied → screening → interview → offer → accepted/rejected +- Exceptions: Rejection can occur at multiple stages; offers may be withdrawn or converted depending on policy + +Implementation guidance: +- Define a canonical set of statuses in the store +- Map each status to display properties (label, color, order) +- Enforce forward-only movement unless explicitly allowed by rules + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Custom Status Creation and Configuration +Custom statuses allow teams to tailor the pipeline to their process. The store should support: +- Creating new statuses with labels and colors +- Ordering custom statuses within the pipeline +- Associating custom statuses with transition rules +- Persisting custom configurations alongside predefined ones + +Operational considerations: +- Prevent duplicate labels +- Ensure ordering does not break transition graph integrity +- Provide defaults for missing attributes (e.g., color) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Transition Rules and Validation Constraints +Transition rules govern which status changes are permitted. Examples include: +- Forward-only transitions for most stages +- Conditional transitions (e.g., moving to offer only after interview) +- Blocking transitions (e.g., cannot move directly from applied to offer) +- Required preconditions (e.g., certain fields must be present before transitioning) + +Validation constraints: +- Disallow invalid transitions with clear error messages +- Enforce required fields before allowing certain moves +- Maintain auditability by recording previous and next statuses + +```mermaid +flowchart TD +Start(["Change Request"]) --> CheckRules["Check Transition Rules"] +CheckRules --> Valid{"Allowed?"} +Valid --> |No| Reject["Reject and show reason"] +Valid --> |Yes| Persist["Persist via Supabase"] +Persist --> UpdateUI["Update UI and visuals"] +Reject --> End(["Done"]) +UpdateUI --> End +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Visual Indicators: Color Coding and Progress Tracking +Visual indicators improve readability and quick scanning: +- Each status has a label and color for immediate recognition +- Progress tracking shows where an application sits in the overall pipeline +- Optional badges or icons indicate special conditions (e.g., pending documents) + +Design recommendations: +- Use consistent color semantics (e.g., green for positive outcomes, red for rejections) +- Provide accessible contrast and tooltips for clarity +- Reflect real-time updates when status changes occur + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) + +### Status Change Operations +Single-item status changes: +- Select an application +- Choose a target status +- Confirm if required by policy +- Observe UI feedback and updated visuals + +Bulk status updates: +- Select multiple applications +- Apply a common status change +- Validate that all selected items satisfy transition rules +- Persist changes atomically where possible + +Integration with tracker interface: +- Inline editing or dropdowns for quick changes +- Confirmation dialogs for destructive or irreversible moves +- Real-time sync and optimistic updates with rollback on failure + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Data Model and Persistence +The database schema defines the core entities and status-related fields. Key aspects: +- Applications table with a status column or related status history table +- Constraints ensuring valid status values +- Indexes for efficient querying by status and timestamps + +Recommendations: +- Normalize status definitions if they evolve frequently +- Keep a status history log for auditability +- Use foreign keys or enums to constrain values + +**Section sources** +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Dependency Analysis +The following diagram maps dependencies among key modules involved in the status pipeline: + +```mermaid +graph LR +Tracker["Tracker.jsx"] --> Store["store.jsx"] +Store --> Supa["supabase.js"] +Supa --> Schema["001_schema.sql"] +Tracker --> UI["components (e.g., Toast.jsx)"] +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Performance Considerations +- Prefer batched updates for bulk operations to reduce network calls +- Use optimistic UI updates with rollback on failure to improve responsiveness +- Cache status metadata locally to avoid repeated lookups +- Index frequently queried fields (status, timestamps) in the database +- Debounce rapid successive changes to prevent excessive writes + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid transition errors: Review transition rules and ensure preconditions are met +- Sync failures: Check Supabase connectivity and retry with exponential backoff +- UI desynchronization: Force refresh or reconcile local state with server state +- Missing status metadata: Verify default values and fallbacks for custom statuses + +Operational tips: +- Log transition attempts and outcomes for diagnostics +- Provide actionable error messages to users +- Offer undo functionality where feasible + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +The status pipeline management system combines a well-defined workflow, flexible customization, robust validation, and clear visual indicators to streamline application tracking. By adhering to transition rules, leveraging bulk operations, and integrating seamlessly with the tracker interface, teams can maintain accurate, up-to-date views of their hiring pipelines while preserving auditability and performance. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Status Tracking & Workflows.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Status Tracking & Workflows.md new file mode 100644 index 0000000..ed18faa --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Status Tracking & Workflows/Status Tracking & Workflows.md @@ -0,0 +1,365 @@ +# Status Tracking & Workflows + + +**Referenced Files in This Document** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the status tracking system and workflows used to manage candidate lifecycle stages, including predefined statuses, custom status creation, automation rules, follow-up actions, visual feedback (color coding and progress indicators), transition rules, audit trails, and reporting based on status changes. It is designed for both technical and non-technical readers, with diagrams and clear explanations. + +## Project Structure +The status tracking system spans UI components, business logic libraries, state management, and database schema: +- UI layer: Tracker component renders the pipeline view and user interactions. +- Logic layer: Follow-ups, next-action recommendations, and statistics are computed by dedicated modules. +- State layer: Centralized store coordinates data access and persistence. +- Data layer: Supabase client and migrations define storage and relationships. + +```mermaid +graph TB +subgraph "UI" +T["Tracker.jsx"] +A["App.jsx"] +end +subgraph "Logic" +F["followups.js"] +N["nextaction.js"] +S["stats.js"] +end +subgraph "State" +ST["store.jsx"] +end +subgraph "Data" +SB["supabase.js"] +DB["001_schema.sql"] +end +T --> F +T --> N +T --> S +T --> ST +ST --> SB +SB --> DB +A --> T +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Core Components +- Tracker component: Provides the primary interface for viewing and updating candidate statuses, rendering pipeline stages, and triggering follow-ups or next actions. +- Follow-ups module: Encapsulates logic for scheduling and managing follow-up tasks tied to status transitions. +- Next-action module: Computes recommended next steps based on current status and context. +- Stats module: Aggregates metrics such as counts per stage, conversion rates, and time-in-stage for reporting. +- Store: Centralizes state, persistence, and synchronization with Supabase. +- Supabase client: Handles data operations and schema-backed queries. + +Key responsibilities: +- Predefined pipeline stages and their order. +- Custom status creation and integration into the pipeline. +- Automation rules that trigger follow-ups and next actions on transitions. +- Visual feedback via color coding and progress indicators. +- Transition validation and audit logging. +- Reporting dashboards driven by status change events. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Architecture Overview +The system follows a layered architecture: +- UI triggers status updates through the Tracker component. +- Business logic validates transitions and computes follow-ups and next actions. +- State layer persists changes and synchronizes with the database. +- Database schema enforces constraints and supports audit trails and analytics. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "Tracker.jsx" +participant Logic as "followups.js / nextaction.js" +participant Store as "store.jsx" +participant DB as "supabase.js / 001_schema.sql" +User->>UI : "Change candidate status" +UI->>Logic : "Validate transition
Compute follow-ups and next action" +Logic-->>UI : "Rules result and suggestions" +UI->>Store : "Persist new status and metadata" +Store->>DB : "Write record and audit entry" +DB-->>Store : "Confirmation" +Store-->>UI : "Updated state" +UI-->>User : "Visual feedback (colors, progress)" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Tracker Component +Responsibilities: +- Renders the status pipeline and candidate cards. +- Handles user interactions to update statuses. +- Displays color-coded stages and progress indicators. +- Invokes follow-up and next-action computations. +- Shows real-time feedback after transitions. + +```mermaid +flowchart TD +Start(["Open Tracker"]) --> Load["Load candidates and statuses"] +Load --> Render["Render pipeline stages"] +Render --> Interact{"User selects status"} +Interact --> |Valid| Validate["Validate transition rules"] +Interact --> |Invalid| ShowError["Show error message"] +Validate --> Compute["Compute follow-ups and next action"] +Compute --> Persist["Persist status change"] +Persist --> UpdateUI["Update colors and progress"] +UpdateUI --> End(["Done"]) +ShowError --> End +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Follow-ups Module +Responsibilities: +- Defines follow-up templates and schedules based on status transitions. +- Integrates with UI to prompt users to create reminders or tasks. +- Supports recurring or one-off follow-ups tied to specific stages. + +```mermaid +classDiagram +class FollowUps { ++createFollowUp(candidateId, fromStatus, toStatus) ++getPendingFollowUps() ++markFollowUpCompleted(id) +-computeDueDate(fromStatus, toStatus) +-applyTemplate(template, context) +} +``` + +**Diagram sources** +- [followups.js](file://src/lib/followups.js) + +**Section sources** +- [followups.js](file://src/lib/followups.js) + +### Next Action Module +Responsibilities: +- Recommends the next best action based on current status and context. +- Uses heuristics or rules to suggest follow-ups, interviews, offers, or rejections. +- Exposes an API for the UI to display actionable guidance. + +```mermaid +classDiagram +class NextAction { ++suggestNextAction(candidateId, currentStatus) +-analyzeContext(candidateId) +-applyRules(currentStatus, context) +} +``` + +**Diagram sources** +- [nextaction.js](file://src/lib/nextaction.js) + +**Section sources** +- [nextaction.js](file://src/lib/nextaction.js) + +### Stats Module +Responsibilities: +- Aggregates counts per stage, conversion rates, and average time-in-stage. +- Provides data for dashboard widgets and export features. +- Supports filtering by date ranges and cohorts. + +```mermaid +classDiagram +class Stats { ++countsByStage() ++conversionRates() ++avgTimeInStage() +-queryCandidates() +-aggregateResults(data) +} +``` + +**Diagram sources** +- [stats.js](file://src/lib/stats.js) + +**Section sources** +- [stats.js](file://src/lib/stats.js) + +### Store Layer +Responsibilities: +- Manages application state for candidates and statuses. +- Persists changes and syncs with Supabase. +- Emits events for UI updates and analytics. + +```mermaid +classDiagram +class Store { ++updateStatus(candidateId, newStatus) ++getPipelineData() ++subscribe(callback) +-persistToSupabase(record) +-emitEvent(event) +} +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### Database Schema +Responsibilities: +- Defines tables for candidates, statuses, transitions, and audit logs. +- Enforces referential integrity and indexes for performance. +- Supports reporting queries and historical analysis. + +```mermaid +erDiagram +CANDIDATES { +uuid id PK +string name +timestamp created_at +timestamp updated_at +} +STATUS_PIPELINE { +uuid id PK +string stage_name UK +int order_index +boolean is_predefined +} +STATUS_TRANSITIONS { +uuid id PK +uuid candidate_id FK +uuid from_status_id FK +uuid to_status_id FK +timestamp occurred_at +string actor +} +AUDIT_LOGS { +uuid id PK +uuid candidate_id FK +string action +jsonb details +timestamp created_at +} +CANDIDATES ||--o{ STATUS_TRANSITIONS : "has many" +STATUS_PIPELINE ||--o{ STATUS_TRANSITIONS : "referenced by" +CANDIDATES ||--o{ AUDIT_LOGS : "logged by" +``` + +**Diagram sources** +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Dependency Analysis +The following diagram shows how components depend on each other and external services: + +```mermaid +graph LR +Tracker["Tracker.jsx"] --> FollowUps["followups.js"] +Tracker --> NextAction["nextaction.js"] +Tracker --> Stats["stats.js"] +Tracker --> Store["store.jsx"] +Store --> Supabase["supabase.js"] +Supabase --> Schema["001_schema.sql"] +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Performance Considerations +- Minimize re-renders by batching status updates and using memoization where appropriate. +- Defer heavy computations (e.g., stats aggregation) to background tasks or cached results. +- Use efficient queries and indexes defined in the schema for frequent filters (by stage, date range). +- Avoid excessive network calls by coalescing writes and leveraging optimistic UI updates. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Invalid status transitions: Ensure transition rules allow the move; check validation logic and error messages in the UI. +- Missing follow-ups: Verify follow-up templates and due date calculations; confirm persistence and retrieval functions. +- Incorrect stats: Validate query filters and aggregation logic; ensure timestamps and stage mappings are correct. +- Sync failures: Inspect Supabase client errors and retry strategies; review schema constraints and permissions. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [followups.js](file://src/lib/followups.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +The status tracking system integrates UI, logic, state, and database layers to provide a robust pipeline for managing candidate stages. It supports predefined and custom statuses, automates follow-ups and next actions, and delivers visual feedback and reporting. Proper validation, audit trails, and performance optimizations ensure reliability and scalability. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Tracker Dashboard & Interface.md b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Tracker Dashboard & Interface.md new file mode 100644 index 0000000..4604b86 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Job Application Tracker/Tracker Dashboard & Interface.md @@ -0,0 +1,275 @@ +# Tracker Dashboard & Interface + + +**Referenced Files in This Document** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [index.css](file://src/index.css) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the Tracker dashboard component, focusing on its main interface layout, navigation structure, and user interaction patterns. It covers how users view job applications in list or grid views, filter and search functionality, sorting options, responsive design considerations, customization (column configuration and display preferences), and performance optimization for large datasets with mobile responsiveness. + +## Project Structure +The Tracker dashboard is implemented as a React component within the application’s components directory. The app shell and routing are provided by the root App component and a shared Layout component. Global state and UI settings are managed via a store module. Styling is centralized in a global CSS file. Data access integrates with Supabase through a dedicated client module. + +```mermaid +graph TB +subgraph "Application Shell" +App["App.jsx"] +Layout["Layout.jsx"] +end +subgraph "Dashboard" +Tracker["Tracker.jsx"] +end +subgraph "State & Data" +Store["store.jsx"] +Supabase["lib/supabase.js"] +end +subgraph "Styling" +Styles["index.css"] +end +App --> Layout +Layout --> Tracker +Tracker --> Store +Tracker --> Supabase +Tracker -.-> Styles +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [index.css](file://src/index.css) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [index.css](file://src/index.css) + +## Core Components +- Tracker: The primary dashboard surface that renders the job applications view, including toolbar controls (search, filters, sort, view toggle), data table/grid, and pagination or infinite scroll behavior. It reads and writes to the store for UI state and uses the Supabase client for data operations. +- Layout: Provides the overall page chrome (header, sidebar, content area) and ensures consistent spacing and responsive breakpoints across pages. +- Store: Centralized state for UI preferences such as active view mode (list/grid), column visibility, sort order, and persisted settings. +- Supabase client: Encapsulates database queries and mutations used by Tracker to load and update job applications. +- index.css: Global styles including responsive rules, grid/table layouts, and utility classes used by Tracker. + +Key responsibilities: +- Tracker orchestrates user interactions (search, filter, sort, view switching) and delegates data fetching to Supabase while updating local store state. +- Layout maintains consistent navigation and responsive scaffolding. +- Store persists user preferences and current dashboard state. +- Supabase client handles remote data synchronization. +- index.css ensures cross-device readability and performance-friendly rendering. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [index.css](file://src/index.css) + +## Architecture Overview +The Tracker dashboard follows a unidirectional data flow pattern: +- User actions in Tracker update local store state. +- Tracker triggers data fetches via the Supabase client based on current filters, search terms, and sort criteria. +- Results are rendered in either a list or grid view depending on the selected mode. +- UI preferences (columns, view mode, sort) are persisted in the store for subsequent sessions. + +```mermaid +sequenceDiagram +participant U as "User" +participant T as "Tracker.jsx" +participant S as "store.jsx" +participant DB as "lib/supabase.js" +U->>T : "Open Dashboard" +T->>S : "Read view mode, columns, sort" +T->>DB : "Fetch applications (filters + sort)" +DB-->>T : "Applications dataset" +T->>T : "Render List/Grid view" +U->>T : "Search / Filter / Sort / Toggle View" +T->>S : "Update UI preferences" +T->>DB : "Re-fetch with new criteria" +DB-->>T : "Updated dataset" +T->>T : "Re-render view" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Tracker Dashboard Interface +The Tracker component provides: +- Main interface layout: A toolbar at the top containing search input, filter controls, sort dropdown, and view toggle (list/grid). Below the toolbar, the main content area displays applications in the selected view. +- Navigation structure: Integrated into the app shell via Layout; Tracker focuses on the dashboard content area without deep nested navigation. +- User interaction patterns: + - Search: Real-time filtering by keywords applied to relevant fields (e.g., company, role, status). + - Filters: Dropdowns or chips for status, source, date range, and other attributes. + - Sorting: Column headers support ascending/descending sorts; default sort can be configured. + - View toggle: Switch between list and grid modes; grid shows cards per application, list shows rows. + - Column configuration: Users can show/hide columns and reorder them; changes persist in the store. + - Display preferences: Theme toggles, density settings, and pagination/infinite scroll behavior. + +Responsive design considerations: +- On small screens, the toolbar collapses into a compact control bar; filters may move to a modal or drawer. +- Grid view switches to single-column cards on narrow devices; list view adapts row wrapping and hides less critical columns. +- Touch-friendly targets and accessible labels ensure usability on mobile. + +Customization examples: +- Column configuration: Enable/disable columns like “Company,” “Role,” “Status,” “Applied Date,” “Next Action.” +- Data display preferences: Choose list vs. grid, set default sort, enable auto-refresh intervals. + +Performance optimization for large datasets: +- Server-side pagination or cursor-based loading to limit payload size. +- Debounced search input to reduce query frequency. +- Memoized derived lists to avoid unnecessary re-renders. +- Virtualized lists for very large datasets when using list view. +- Efficient Supabase queries with selective field projection and indexed filters. + +Mobile responsiveness: +- Breakpoints adjust layout from multi-column grid to single-column cards. +- Collapsible filters and sticky header for quick access to controls. +- Optimized image sizes and lazy-loading for any media in grid cards. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [index.css](file://src/index.css) + +### Layout Integration +The Layout component wraps Tracker within the application shell, providing: +- Header and sidebar navigation for other features (Account, Settings, etc.). +- Consistent spacing, typography, and responsive behavior. +- Content area where Tracker renders its dashboard. + +Interaction patterns: +- Breadcrumb or active route highlighting indicates the current page. +- Keyboard shortcuts and focus management improve accessibility. + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) + +### State Management and Preferences +The store manages: +- Active view mode (list/grid). +- Column visibility and order. +- Current filters, search term, and sort configuration. +- Persistence of preferences across sessions. + +Data flow: +- Tracker reads initial preferences from the store. +- User actions update the store synchronously. +- Tracker reacts to store changes and triggers data refreshes via Supabase. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Data Access and Sync +The Supabase client encapsulates: +- Fetching applications with filters, search, and sort parameters. +- Mutations for updates (e.g., changing status or next action). +- Error handling and retry strategies. + +Integration points: +- Tracker composes query parameters from store state and calls the client. +- Results are normalized before rendering to ensure stable keys and efficient updates. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +### Styling and Responsive Behavior +Global styles define: +- Grid and table layouts for list and card views. +- Breakpoints for mobile-first responsiveness. +- Utility classes for spacing, alignment, and visual hierarchy. + +Best practices: +- Use semantic HTML elements for better accessibility. +- Ensure sufficient color contrast and keyboard navigability. +- Avoid heavy animations on low-end devices. + +**Section sources** +- [index.css](file://src/index.css) + +## Dependency Analysis +The Tracker component depends on: +- Local store for UI state and preferences. +- Supabase client for data retrieval and updates. +- Global styles for layout and responsiveness. +- Layout component for integration into the app shell. + +```mermaid +graph LR +Tracker["Tracker.jsx"] --> Store["store.jsx"] +Tracker --> Supabase["lib/supabase.js"] +Tracker --> Styles["index.css"] +Layout["Layout.jsx"] --> Tracker +App["App.jsx"] --> Layout +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [index.css](file://src/index.css) +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [index.css](file://src/index.css) +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Pagination and virtualization: Prefer server-side pagination or cursor-based loading; consider virtual scrolling for long lists. +- Debouncing and throttling: Apply debounced search and throttled resize handlers to minimize re-renders and network requests. +- Selective field projection: Request only necessary fields from Supabase to reduce payload size. +- Memoization: Cache computed lists and derived state to prevent redundant calculations. +- Efficient updates: Use unique identifiers and batched updates to keep React reconciliation fast. +- Mobile optimizations: Lazy-load images, avoid heavy CSS transforms, and prefer simple transitions. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Data not loading: Verify Supabase client initialization and permissions; check network errors and retry logic. +- Filters not applying: Ensure store state updates trigger re-fetches; confirm query parameter composition. +- Slow rendering: Inspect list length and consider virtualization; review memoization and key stability. +- Mobile layout breaks: Check breakpoint definitions and container widths; validate touch target sizes. +- Preferences not persisting: Confirm store persistence mechanism and storage availability. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +## Conclusion +The Tracker dashboard delivers a flexible, responsive interface for managing job applications. With configurable views, robust filtering and sorting, and persistent preferences, it supports both desktop and mobile workflows. By leveraging server-side pagination, memoization, and efficient queries, the dashboard remains performant even with large datasets. The modular architecture—separating UI state, data access, and styling—facilitates maintainability and future enhancements. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Comparison Tools & Matrix.md b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Comparison Tools & Matrix.md new file mode 100644 index 0000000..91d2db1 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Comparison Tools & Matrix.md @@ -0,0 +1,331 @@ +# Comparison Tools & Matrix + + +**Referenced Files in This Document** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [csv.js](file://src/lib/csv.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the offer comparison tools and matrix interface that allow users to view multiple offers side-by-side, compare key attributes, filter and sort data, and export results for further analysis. It covers the comparison matrix layout, filtering options, sorting capabilities, visual indicators that highlight differences between offers, example comparison scenarios, custom view configurations, and export functionality. + +## Project Structure +The comparison features are implemented primarily in the Offers page component and supporting libraries: +- The Offers page orchestrates the comparison UI, including the matrix, filters, and actions. +- The Result View supports detailed per-offer insights and can be integrated into the comparison workflow. +- The global store manages selected offers, comparison state, and user preferences. +- Libraries provide scoring, pricing normalization, statistics, and CSV export utilities used by the comparison matrix. + +```mermaid +graph TB +subgraph "UI" +OP["OffersPage.jsx"] +RV["ResultView.jsx"] +end +subgraph "State" +ST["store.jsx"] +end +subgraph "Libraries" +SC["scoring.js"] +PR["pricing.js"] +SS["stats.js"] +CS["csv.js"] +end +OP --> ST +OP --> SC +OP --> PR +OP --> SS +OP --> CS +RV --> ST +RV --> SC +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) + +## Core Components +- Offers Page: Central entry point for comparing multiple offers. It renders the comparison matrix, provides filters and sorting controls, and exposes export actions. +- Result View: Displays detailed analysis for a single offer; can be opened from the matrix for deeper inspection. +- Store: Holds the list of offers, selected subset for comparison, active filters/sort keys, and view configuration (columns, grouping). +- Scoring Library: Computes normalized scores and highlights relative strengths across offers. +- Pricing Library: Normalizes compensation components (base, bonus, equity, benefits) for consistent comparison. +- Stats Library: Calculates summary metrics (min/max/median/mean) to support highlighting and ranking. +- CSV Export: Serializes the current comparison matrix to CSV for offline analysis. + +Key responsibilities: +- Rendering a grid where each column represents an offer and each row represents a comparison attribute. +- Applying filters to narrow down which offers appear in the matrix. +- Sorting columns or rows based on selected criteria. +- Highlighting differences using color or badges when values diverge across offers. +- Allowing users to customize visible columns and persist preferences. +- Exporting the current matrix to CSV. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) + +## Architecture Overview +The comparison system follows a unidirectional data flow: +- User interactions (filters, sort, selection) update the store. +- Offers Page reads from the store and computes derived views (filtered, sorted, highlighted). +- Libraries transform raw offer data into comparable units (scores, normalized prices, stats). +- Export action serializes the current view to CSV. + +```mermaid +sequenceDiagram +participant U as "User" +participant OP as "OffersPage.jsx" +participant ST as "store.jsx" +participant SC as "scoring.js" +participant PR as "pricing.js" +participant SS as "stats.js" +participant CS as "csv.js" +U->>OP : "Select offers / Apply filters / Sort" +OP->>ST : "Update selection, filters, sort" +OP->>SC : "Compute scores for selected offers" +OP->>PR : "Normalize pricing fields" +OP->>SS : "Compute min/max/median for highlights" +OP-->>U : "Render comparison matrix with highlights" +U->>OP : "Export to CSV" +OP->>CS : "Serialize current matrix" +CS-->>U : "Download CSV file" +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) + +## Detailed Component Analysis + +### Comparison Matrix Layout +- Columns represent individual offers; rows represent comparison attributes such as base salary, bonus, equity, benefits, location, role level, and computed score. +- Cells display normalized values or human-readable summaries. When values differ significantly across offers, cells are visually highlighted (e.g., color-coded or badge-based) to draw attention. +- Sticky headers and optional sticky first column improve readability for wide matrices. +- Column ordering can be customized via drag-and-drop or menu reordering. + +Visual indicators: +- Best/worst highlighting per row based on computed stats. +- Difference badges when values deviate beyond thresholds. +- Score bars or mini sparklines for quick trend visualization within a cell. + +Customization: +- Toggle visibility of specific columns (attributes). +- Group offers by team, location, or seniority if available. +- Persist preferred column order and visibility in local storage. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [stats.js](file://src/lib/stats.js) + +### Filtering Options +Filters enable narrowing the set of offers displayed in the matrix: +- Role type, company, location, compensation band, and other metadata. +- Numeric range filters for base salary, bonus, equity value, and total comp. +- Boolean toggles for benefits (e.g., remote eligibility, signing bonus presence). +- Combined filters apply logical AND semantics unless otherwise specified. + +Filter behavior: +- Filters update the store and trigger a re-render of the matrix. +- Active filters are shown as chips with clear/reset actions. +- Filter suggestions may be provided based on current dataset distribution. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) + +### Sorting Capabilities +Sorting supports both ascending and descending orders: +- Sort by any column header to rank offers by that attribute. +- Multi-column sort is supported by holding modifier keys while clicking additional headers. +- Default sort can be configured (e.g., by overall score or total compensation). + +Sorting behavior: +- Stable sort preserves original order for equal keys. +- Numeric and string sorts are handled appropriately; dates and enums have locale-aware ordering. +- Sorting persists in the store and applies to the exported CSV. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) + +### Visual Indicators That Highlight Differences +- Row-level best/worst markers identify top and bottom performers per attribute. +- Threshold-based difference badges indicate significant deviations across offers. +- Color coding uses accessible palettes to ensure clarity for all users. +- Optional “diff-only” mode hides identical cells to focus on disparities. + +Implementation notes: +- Stats library computes min/max/median to determine thresholds. +- Scoring library normalizes heterogeneous inputs for fair comparisons. +- Pricing library ensures consistent currency and unit handling. + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +### Example Comparison Scenarios +- Side-by-side compensation review: Compare base, bonus, equity, and benefits across three offers to decide the highest total compensation. +- Role fit assessment: Compare role level, responsibilities, and growth opportunities alongside compensation. +- Location and flexibility trade-offs: Evaluate remote policies, relocation packages, and cost-of-living adjustments. +- Time-sensitive decisions: Use diff-only mode to quickly spot unique perks or constraints. + +These scenarios are facilitated by the matrix’s flexible column set, robust filtering, and clear visual indicators. + +[No sources needed since this section doesn't analyze specific files] + +### Custom View Configurations +Users can tailor the matrix to their needs: +- Choose which attributes to display. +- Reorder columns to prioritize important factors. +- Save presets for common comparisons (e.g., “Engineering vs Product,” “Remote vs On-site”). +- Persist preferences locally for seamless return visits. + +Configuration persistence: +- Preferences are stored in the store and synced to local storage. +- Presets can be shared via links or imported/exported as JSON. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +### Export Functionality +Export allows saving the current comparison matrix for offline analysis: +- CSV includes selected columns, filtered and sorted rows. +- Headers reflect user-visible labels; numeric fields use normalized units. +- Optional inclusion of computed scores and highlights metadata. + +Export workflow: +- User triggers export from the Offers page. +- CSV library serializes the current view. +- Browser downloads the generated file. + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +## Dependency Analysis +The comparison matrix depends on several modules: +- Offers Page composes UI and delegates computations to libraries. +- Store centralizes state and provides reactive updates. +- Scoring and Pricing libraries normalize and compute comparative metrics. +- Stats library supplies aggregate measures for highlighting. +- CSV library handles serialization. + +```mermaid +graph LR +OP["OffersPage.jsx"] --> ST["store.jsx"] +OP --> SC["scoring.js"] +OP --> PR["pricing.js"] +OP --> SS["stats.js"] +OP --> CS["csv.js"] +RV["ResultView.jsx"] --> ST +RV --> SC +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) + +## Performance Considerations +- Memoize derived views (filtered, sorted, highlighted) to avoid recomputation on every render. +- Debounce filter input changes to reduce frequent re-renders. +- Virtualize large matrices if many offers or columns are present. +- Normalize pricing and scores once per offer and cache results. +- Limit highlight calculations to visible rows/columns when possible. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing or inconsistent data: Ensure required fields exist before computing scores or highlights; fallback to neutral values when missing. +- Incorrect sorting: Verify locale-aware collation for strings and correct numeric parsing. +- Export anomalies: Confirm CSV encoding and delimiter choices; validate headers match visible columns. +- Performance lag: Check for unnecessary re-renders; add memoization and debouncing as needed. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +## Conclusion +The comparison tools and matrix interface provide a powerful, customizable way to evaluate multiple offers side-by-side. With robust filtering, sorting, visual indicators, and export capabilities, users can make informed decisions efficiently. The modular architecture separates concerns between UI, state, computation, and export, enabling maintainability and extensibility. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### API Reference Summary +- Offers Page: Renders matrix, manages filters/sort, triggers export. +- Store: Manages selection, filters, sort, and view config. +- Scoring: Computes normalized scores across offers. +- Pricing: Normalizes compensation components for fair comparison. +- Stats: Provides min/max/median for highlighting logic. +- CSV: Serializes current matrix to downloadable file. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [pricing.js](file://src/lib/pricing.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Offer Input & Management.md b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Offer Input & Management.md new file mode 100644 index 0000000..d040ddf --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Offer Input & Management.md @@ -0,0 +1,341 @@ +# Offer Input & Management + + +**Referenced Files in This Document** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [supabase.js](file://src/lib/supabase.js) +- [cloud.js](file://src/lib/cloud.js) +- [App.jsx](file://src/App.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the offer input and management system centered around the OffersPage component. It covers how users add new job offers, edit existing ones, and manage offer data end-to-end. You will find: +- The form fields for compensation details, benefits, requirements, and other offer attributes +- Examples of the offer data structure and validation rules +- User interaction patterns for creating, editing, and deleting offers +- How CRUD operations are implemented and where data is stored and retrieved (local storage and optional cloud sync) + +## Project Structure +The offer feature spans a small set of components and libraries: +- UI layer: OffersPage renders the list, forms, and actions +- State layer: store.jsx provides global state and actions for offers +- Persistence layer: storage.js handles local persistence; supabase.js and cloud.js handle optional cloud sync + +```mermaid +graph TB +App["App.jsx"] --> OffersPage["OffersPage.jsx"] +OffersPage --> Store["store.jsx"] +Store --> Storage["storage.js"] +Store --> Cloud["cloud.js"] +Cloud --> Supabase["supabase.js"] +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Core Components +- OffersPage: Provides the user interface to view, create, edit, and delete offers. It renders lists, detail views, and forms for compensation, benefits, requirements, and additional attributes. +- Store (store.jsx): Centralized state for offers with actions to add, update, remove, and persist offers. It may also coordinate syncing with cloud storage. +- Storage (storage.js): Local persistence utilities for reading/writing offers to the browser’s storage. +- Cloud (cloud.js): Optional synchronization helpers that use Supabase client to persist offers remotely. +- Supabase client (supabase.js): Configuration and client instance used by cloud.js. + +Key responsibilities: +- Rendering and validating offer forms +- Managing offer lifecycle (create, read, update, delete) +- Persisting changes locally and optionally to the cloud +- Exposing actions to the UI via the store + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Architecture Overview +The offer system follows a unidirectional data flow: +- User interactions in OffersPage trigger store actions +- Store updates local state and persists to storage.js +- Optionally, store triggers cloud sync via cloud.js using supabase.js +- UI re-renders based on updated store state + +```mermaid +sequenceDiagram +participant U as "User" +participant OP as "OffersPage.jsx" +participant S as "store.jsx" +participant ST as "storage.js" +participant CL as "cloud.js" +participant SB as "supabase.js" +U->>OP : "Add/Edit/Delete Offer" +OP->>S : "Dispatch action (add/update/remove)" +S->>ST : "Persist locally" +alt "Cloud sync enabled" +S->>CL : "Sync operation" +CL->>SB : "Call Supabase API" +SB-->>CL : "Result" +CL-->>S : "Sync status" +end +S-->>OP : "State updated" +OP-->>U : "Updated UI" +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### OffersPage Component +Responsibilities: +- Display the current list of offers +- Open forms to add or edit an offer +- Validate inputs before submission +- Trigger store actions for create, update, and delete +- Show feedback (e.g., success/error states) + +Form fields typically include: +- Compensation details: base salary, currency, pay frequency, bonuses, equity, sign-on bonus +- Benefits: health insurance, retirement plans, PTO, remote/hybrid options, relocation +- Requirements: skills, experience level, education, certifications, work authorization +- Other attributes: company name, role title, location, start date, offer status, notes + +Validation rules: +- Required fields such as company, role, and compensation amount +- Numeric ranges and currency formatting for monetary values +- Date parsing and future-date checks for start dates +- List-based fields (benefits, requirements) support adding/removing items + +User interaction patterns: +- Add new offer: open a blank form, fill fields, submit to create +- Edit existing offer: select an offer, populate form, modify fields, submit to update +- Delete offer: confirm deletion, then remove from list and storage + +CRUD operations: +- Create: dispatch add action, persist locally, optionally sync +- Read: load offers from storage into store, render in UI +- Update: dispatch update action with modified fields, persist and sync +- Delete: dispatch remove action, persist and sync + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +### Store (store.jsx) +Responsibilities: +- Maintain offers state (list, selected item, loading flags) +- Provide actions for add, update, remove, and bulk operations +- Coordinate persistence with storage.js +- Trigger cloud sync via cloud.js when configured + +Data flow: +- Actions receive normalized offer payloads +- Store merges changes and writes to storage +- On successful local write, store calls cloud sync if enabled +- UI subscribes to store updates and re-renders + +Error handling: +- Catches storage errors and surfaces them to UI +- Handles network failures during cloud sync and retries or queues operations + +**Section sources** +- [store.jsx](file://src/store.jsx) + +### Storage (storage.js) +Responsibilities: +- Read/write offers to local storage +- Ensure schema compatibility across versions +- Provide atomic updates and safe defaults + +Operations: +- getOffers(): returns current list +- saveOffers(offers): persists the full list +- appendOffer(offer): adds a single offer +- updateOffer(id, changes): partial update by id +- removeOffer(id): deletes an offer by id + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### Cloud Sync (cloud.js and supabase.js) +Responsibilities: +- cloud.js: wraps Supabase calls for offers (CRUD), manages conflict resolution and retry logic +- supabase.js: initializes and exports the Supabase client + +Flow: +- After local persistence, store invokes cloud sync +- cloud.js performs upserts/deletes on the server +- Errors are logged and surfaced to store for UI feedback + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +### App Integration (App.jsx) +Responsibilities: +- Mounts OffersPage within the application layout +- Ensures store is available globally for OffersPage to consume + +**Section sources** +- [App.jsx](file://src/App.jsx) + +## Dependency Analysis +The following diagram shows how modules depend on each other for offer management: + +```mermaid +graph LR +OffersPage["OffersPage.jsx"] --> Store["store.jsx"] +Store --> Storage["storage.js"] +Store --> Cloud["cloud.js"] +Cloud --> Supabase["supabase.js"] +App["App.jsx"] --> OffersPage +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Batch updates: group multiple changes to minimize storage writes +- Debounced saves: avoid excessive writes while typing in long forms +- Lazy rendering: paginate or virtualize large offer lists +- Selective sync: only sync changed fields to reduce network overhead +- Error backoff: exponential backoff for failed cloud sync attempts + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Form validation errors: ensure required fields are filled and numeric/date formats are correct +- Local storage quota exceeded: clear unused offers or migrate to cloud-only mode +- Cloud sync failures: check network connectivity, credentials, and server availability; retry after transient errors +- Data inconsistency: verify that local storage and cloud records match; consider a reconciliation step + +Operational tips: +- Inspect store state to confirm actions were dispatched +- Check storage logs for write/read errors +- Review cloud sync logs for HTTP status codes and error messages + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +The offer input and management system provides a cohesive workflow for creating, editing, and deleting job offers. OffersPage drives user interactions, store.jsx orchestrates state and persistence, storage.js ensures reliable local saving, and cloud.js with supabase.js enables optional cloud synchronization. By following the documented data structures, validation rules, and interaction patterns, users can confidently manage their offers both offline and online. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Offer Data Model +A typical offer record includes: +- Identification: id, createdAt, updatedAt +- Role info: company, roleTitle, location, startDate, status +- Compensation: baseSalary, currency, payFrequency, bonus, equity, signOnBonus +- Benefits: healthInsurance, retirementPlan, ptoDays, remoteOption, relocation +- Requirements: skills[], experienceLevel, education, certifications, workAuthorization +- Notes: description, attachments[] + +Example payload shape (illustrative): +{ + "id": "string", + "company": "string", + "roleTitle": "string", + "location": "string", + "startDate": "YYYY-MM-DD", + "status": "string", + "compensation": { + "baseSalary": "number", + "currency": "string", + "payFrequency": "string", + "bonus": "number", + "equity": "object", + "signOnBonus": "number" + }, + "benefits": ["string"], + "requirements": ["string"], + "notes": "string", + "createdAt": "ISO timestamp", + "updatedAt": "ISO timestamp" +} + +[No sources needed since this section provides conceptual model examples] + +### Validation Rules Summary +- Required fields: company, roleTitle, compensation.baseSalary +- Monetary fields: non-negative numbers with valid currency codes +- Dates: ISO format, startDate must be valid and not in the past unless explicitly allowed +- Lists: benefits and requirements accept zero or more strings +- Status: one of predefined enum values (e.g., received, negotiating, accepted, declined) + +[No sources needed since this section provides conceptual rules] + +### User Interaction Flow +```mermaid +flowchart TD +Start(["Open OffersPage"]) --> ViewList["View Offers List"] +ViewList --> AddNew{"Add New Offer?"} +AddNew --> |Yes| OpenForm["Open Add/Edit Form"] +AddNew --> |No| EditExisting{"Edit Existing Offer?"} +EditExisting --> |Yes| OpenForm +EditExisting --> |No| End(["Exit"]) +OpenForm --> Validate["Validate Inputs"] +Validate --> Valid{"Valid?"} +Valid --> |No| ShowErrors["Show Validation Errors"] +ShowErrors --> OpenForm +Valid --> |Yes| Submit["Submit to Store"] +Submit --> Persist["Persist Locally"] +Persist --> Sync{"Cloud Sync Enabled?"} +Sync --> |Yes| DoSync["Sync with Server"] +Sync --> |No| Done["Done"] +DoSync --> Done +Done --> Refresh["Refresh UI"] +Refresh --> End +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Offer Management & Comparison.md b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Offer Management & Comparison.md new file mode 100644 index 0000000..b42c13e --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Offer Management & Comparison.md @@ -0,0 +1,362 @@ +# Offer Management & Comparison + + +**Referenced Files in This Document** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the offer management and comparison system that helps users input, compare, and analyze multiple job offers side-by-side. It covers compensation analysis tools, red flag detection, scoring algorithms, decision support features, the comparison matrix, weighted scoring, and visualization aids. Examples are provided for offer entry, comparison scenarios, and interpreting results to guide informed decisions. + +## Project Structure +The feature is implemented primarily through a React component for the user interface and several library modules for analysis, scoring, red flags, statistics, CSV import/export, and storage. The store coordinates state across the application. + +```mermaid +graph TB +UI["OffersPage.jsx"] --> Store["store.jsx"] +UI --> Analyze["analyze.js"] +UI --> RedFlags["redflags.js"] +UI --> Scoring["scoring.js"] +UI --> Stats["stats.js"] +UI --> CSV["csv.js"] +UI --> Storage["storage.js"] +Analyze --> Stats +Analyze --> Scoring +Analyze --> RedFlags +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) + +## Core Components +- Offers page: Provides the primary UI for entering offers, viewing them side-by-side, running analyses, exporting/importing data, and persisting progress. +- Analysis engine: Aggregates compensation metrics, computes totals, and prepares normalized values for comparison. +- Red flag detector: Identifies potential risks or inconsistencies in offer terms (e.g., missing components, unusual ratios). +- Scoring system: Applies configurable weights to criteria and produces composite scores for ranking offers. +- Statistics helpers: Computes summary metrics useful for comparisons and visualizations. +- CSV utilities: Import and export offers for sharing and backup. +- Storage: Persists offers locally so users can continue work across sessions. +- Store: Centralized state for offers, settings, and computed results. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview +The system follows a clear separation between UI and logic: +- The UI layer renders the comparison matrix and controls. +- The analysis pipeline transforms raw inputs into structured metrics. +- The red flag module inspects inputs for warnings. +- The scoring module applies weights to produce ranked outcomes. +- Utilities handle persistence and CSV operations. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "OffersPage.jsx" +participant Store as "store.jsx" +participant Analyze as "analyze.js" +participant Flags as "redflags.js" +participant Score as "scoring.js" +participant Stats as "stats.js" +participant CSV as "csv.js" +participant Storage as "storage.js" +User->>UI : "Enter or import offers" +UI->>Store : "Update offers state" +Store-->>UI : "State updated" +UI->>Analyze : "Compute compensation metrics" +Analyze->>Stats : "Summaries and normalization" +UI->>Flags : "Detect red flags" +UI->>Score : "Apply weighted scoring" +UI->>CSV : "Export/Import offers" +UI->>Storage : "Persist offers and settings" +UI-->>User : "Comparison matrix + insights" +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) + +## Detailed Component Analysis + +### Offers Page (UI and Orchestration) +Responsibilities: +- Collects offer entries via forms and CSV import. +- Displays a side-by-side comparison matrix with key fields and computed insights. +- Triggers analysis, red flag checks, and scoring. +- Exports results and persists data. + +Key interactions: +- Reads/writes offers from/to the store. +- Invokes analysis, red flags, and scoring modules. +- Uses CSV utilities for import/export. +- Persists changes using storage utilities. + +```mermaid +flowchart TD +Start(["Open Offers Page"]) --> Load["Load offers from storage"] +Load --> Render["Render comparison matrix"] +Render --> Input{"New offer or edit?"} +Input --> |Yes| Update["Update store with new/edited offer"] +Update --> Persist["Persist to storage"] +Persist --> RunAnalysis["Run analysis pipeline"] +Input --> |No| RunAnalysis +RunAnalysis --> Flags["Run red flag detection"] +Flags --> Score["Compute weighted scores"] +Score --> Visualize["Render insights and rankings"] +Visualize --> Export{"Export/Import?"} +Export --> |Export| CSVOut["Use CSV export"] +Export --> |Import| CSVIn["Use CSV import"] +CSVOut --> End(["Done"]) +CSVIn --> End +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [storage.js](file://src/lib/storage.js) +- [csv.js](file://src/lib/csv.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [storage.js](file://src/lib/storage.js) +- [csv.js](file://src/lib/csv.js) + +### Compensation Analysis Engine +Purpose: +- Normalizes and aggregates compensation components (base salary, bonuses, equity, benefits, allowances). +- Produces comparable totals and breakdowns across offers. +- Prepares normalized values for fair comparison when currencies or frequencies differ. + +Processing logic: +- Parse and validate numeric fields. +- Normalize recurring vs one-time payments. +- Aggregate subtotals by category. +- Provide per-offer summaries for visualization. + +```mermaid +flowchart TD +A["Raw offer fields"] --> B["Validate and parse numbers"] +B --> C["Normalize frequency/currency"] +C --> D["Aggregate by category"] +D --> E["Compute totals and breakdowns"] +E --> F["Normalized metrics for comparison"] +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [stats.js](file://src/lib/stats.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [stats.js](file://src/lib/stats.js) + +### Red Flag Detection System +Purpose: +- Highlights potential risks or inconsistencies in offer terms. +- Surfaces missing components, unusual ratios, or policy concerns. + +Detection approach: +- Inspect presence of expected fields. +- Compute ratios (e.g., bonus-to-base, equity vesting gaps). +- Apply rule-based heuristics to generate warnings. + +```mermaid +flowchart TD +S["Offer data"] --> CheckFields["Check required fields"] +CheckFields --> Ratios["Compute ratio checks"] +Ratios --> Rules["Apply heuristic rules"] +Rules --> Warnings["Generate red flags list"] +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) + +### Weighted Scoring and Ranking +Purpose: +- Converts multi-criteria offer attributes into a single score for ranking. +- Allows users to adjust weights to reflect personal priorities. + +Scoring workflow: +- Select criteria (e.g., base pay, bonus, equity, benefits, location, growth). +- Assign weights per criterion. +- Normalize each criterion across offers. +- Compute weighted sum to derive final scores. +- Rank offers by score. + +```mermaid +flowchart TD +I["Criteria and weights"] --> N["Normalize criterion values"] +N --> W["Multiply by weights"] +W --> Sum["Sum weighted values"] +Sum --> Rank["Rank offers by total score"] +``` + +**Diagram sources** +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) + +### Visualization and Decision Support +Features: +- Side-by-side comparison matrix showing key metrics and computed insights. +- Summary charts and highlights derived from analysis and scoring. +- Ranked list of offers based on weighted scoring. +- Exportable reports for sharing or archiving. + +Integration points: +- Pulls normalized metrics from the analysis engine. +- Incorporates red flags into the view for quick risk awareness. +- Reflects current weights and resulting rankings. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) + +### Data Persistence and Sharing +- Local storage ensures offers survive refreshes and device restarts. +- CSV import/export enables sharing offers across devices or collaborators. + +Operations: +- Save offers and settings automatically after edits. +- Import CSV to bulk-add offers. +- Export current set for backup or review. + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [csv.js](file://src/lib/csv.js) + +## Dependency Analysis +High-level dependencies among modules: + +```mermaid +graph LR +OffersPage["OffersPage.jsx"] --> Store["store.jsx"] +OffersPage --> Analyze["analyze.js"] +OffersPage --> RedFlags["redflags.js"] +OffersPage --> Scoring["scoring.js"] +OffersPage --> Stats["stats.js"] +OffersPage --> CSV["csv.js"] +OffersPage --> Storage["storage.js"] +Analyze --> Stats +Analyze --> Scoring +Analyze --> RedFlags +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [csv.js](file://src/lib/csv.js) +- [storage.js](file://src/lib/storage.js) + +## Performance Considerations +- Keep the number of offers reasonable for smooth rendering; consider pagination or filtering if the dataset grows large. +- Debounce heavy computations (analysis, scoring) during rapid edits. +- Cache normalized metrics and red flags to avoid recomputation unless inputs change. +- Use efficient CSV parsing and streaming for large imports. +- Avoid unnecessary re-renders by memoizing derived data where possible. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing or invalid numeric fields: Ensure all monetary and percentage fields are valid numbers before analysis. +- Currency/frequency mismatches: Normalize inputs consistently to avoid skewed totals. +- Unexpected red flags: Review flagged items and correct underlying data or adjust thresholds if appropriate. +- Scores not updating: Verify weights and normalization steps; ensure inputs changed and triggered recomputation. +- Data loss: Confirm local storage availability and permissions; use CSV export regularly as a backup. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [storage.js](file://src/lib/storage.js) +- [csv.js](file://src/lib/csv.js) + +## Conclusion +The offer management and comparison system provides a cohesive workflow for entering offers, analyzing compensation, detecting red flags, and ranking options with a transparent, weighted scoring model. The side-by-side matrix and derived insights help users make confident, data-driven decisions. Robust persistence and CSV sharing further enhance usability and collaboration. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Example: Offer Entry and Comparison Scenario +- Enter two offers with different structures (e.g., higher base vs higher bonus/equity). +- Run analysis to see normalized totals and breakdowns. +- Review red flags for any missing components or unusual ratios. +- Adjust weights to prioritize base pay, bonus, or equity. +- Compare rankings and choose the best fit for your goals. + +[No sources needed since this section provides conceptual examples] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Red Flag Detection System.md b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Red Flag Detection System.md new file mode 100644 index 0000000..167e9aa --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Red Flag Detection System.md @@ -0,0 +1,288 @@ +# Red Flag Detection System + + +**Referenced Files in This Document** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultsView.jsx](file://src/components/ResultView.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the red flag detection system that identifies potential issues in job offers. It covers categories of red flags, detection rules, severity levels, alert mechanisms, and how common problematic patterns are recognized (for example, unrealistic expectations, compensation issues, or contract concerns). It also includes examples of detected red flags, guidance for customizing detection rules, interpreting flagged issues, and an overview of test coverage and rule validation processes. + +## Project Structure +The red flag detection logic is implemented as a library module with dedicated tests. The UI integrates with this library to present results and alerts to users. + +```mermaid +graph TB +subgraph "Library" +RF["redflags.js"] +TEST["redflags.test.js"] +ANA["analyze.js"] +SCORE["scoring.js"] +PROMPT["prompt.js"] +AI["ai.js"] +end +subgraph "UI" +RV["ResultView.jsx"] +OP["OffersPage.jsx"] +end +OP --> RF +OP --> ANA +RV --> RF +RV --> SCORE +RF --> PROMPT +RF --> AI +TEST --> RF +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +## Core Components +- Red flag engine: Centralized detection rules and categorization of issues found in job offer text. +- Severity model: Each red flag has a severity level used to prioritize alerts. +- Alerting integration: UI components consume red flag results to display warnings and recommendations. +- Scoring linkage: Red flags may influence overall offer scoring and summary generation. +- Prompt/AI assistance: Optional prompts or AI-based analysis can augment rule-based detection. + +Key responsibilities: +- Parse and normalize input text from job offers. +- Apply rule sets across multiple categories (expectations, compensation, contract terms, etc.). +- Produce structured findings with category, severity, and suggested actions. +- Expose APIs for UI rendering and analytics. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) + +## Architecture Overview +The red flag detection system follows a layered architecture: +- Input layer: Accepts raw offer text or structured fields. +- Rule engine: Applies deterministic checks and heuristics. +- Aggregation layer: Combines findings into a unified result set. +- Output layer: Emits alerts, summaries, and optional AI-enhanced insights. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "OffersPage.jsx" +participant Engine as "redflags.js" +participant Score as "scoring.js" +participant View as "ResultView.jsx" +User->>UI : "Submit offer text" +UI->>Engine : "DetectRedFlags(text)" +Engine-->>UI : "Findings {category, severity, details}" +UI->>Score : "Compute score using findings" +Score-->>UI : "Score + summary" +UI->>View : "Render alerts and recommendations" +View-->>User : "Display red flags and next steps" +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Detailed Component Analysis + +### Red Flag Categories and Rules +Categories typically include: +- Unrealistic expectations: Overly aggressive timelines, vague deliverables, or scope creep indicators. +- Compensation issues: Missing salary ranges, ambiguous bonus structures, or non-standard pay terms. +- Contract concerns: Non-compete clauses, IP assignment, termination conditions, or equity ambiguities. +- Role clarity: Unclear responsibilities, reporting lines, or performance metrics. +- Compliance and benefits: Missing statutory benefits, unclear leave policies, or remote work constraints. + +Detection approach: +- Keyword and phrase matching with contextual normalization. +- Numeric thresholds and range validations (e.g., missing or out-of-range values). +- Structural checks for required sections or clauses. +- Cross-field consistency checks (e.g., role vs. responsibilities alignment). + +Severity levels: +- Critical: Immediate risk requiring attention before acceptance. +- High: Significant concern that should be clarified or mitigated. +- Medium: Moderate risk; consider negotiation or documentation. +- Low: Minor issue; informational or best-practice recommendation. + +Alert mechanisms: +- In-app notifications and banners. +- Highlighted sections within the offer view. +- Exportable summary for sharing with advisors. + +Examples of detected red flags: +- “Unrealistic expectations” flagged when deadlines are extremely short without justification. +- “Compensation ambiguity” flagged when total compensation components are not itemized. +- “Contract risk” flagged when restrictive clauses are present without clear exceptions. + +Customization: +- Toggle categories on/off via configuration. +- Adjust keyword lists and thresholds per region or industry. +- Add custom rules by extending the rule registry. + +Guidance for interpretation: +- Review each finding’s category and severity. +- Use suggested actions to negotiate or request clarifications. +- Prioritize critical and high-severity items first. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) + +### Rule Validation and Test Coverage +Testing strategy: +- Unit tests validate individual rules against positive and negative cases. +- Integration tests verify end-to-end detection flows and output structure. +- Edge case coverage ensures robustness against malformed inputs. + +Validation process: +- Run the test suite to confirm all rules pass expected outcomes. +- Add new tests when introducing or modifying rules. +- Maintain regression guards for existing detections. + +Coverage highlights: +- Category-specific assertions ensure balanced detection across domains. +- Severity mapping verified through explicit expectations. +- Output schema validated to guarantee consistent consumption by UI. + +**Section sources** +- [redflags.test.js](file://src/lib/redflags.test.js) + +### Integration with Scoring and Summaries +Scoring linkage: +- Red flags contribute to an overall offer score by penalizing risky areas. +- Weighting can vary by category severity. + +Summaries and prompts: +- Summaries aggregate top findings and recommended next steps. +- Prompts may guide users on what to clarify during negotiations. + +AI augmentation: +- Optional AI-based analysis can provide additional context or suggestions based on detected patterns. + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) + +### UI Presentation and Alerts +Presentation: +- Offers page triggers detection and displays initial alerts. +- Results view renders detailed findings, severity badges, and actionable tips. + +Accessibility and UX: +- Clear labeling of severity levels. +- Expandable details for each red flag. +- Option to export or share findings. + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Dependency Analysis +The red flag engine depends on utility modules for prompting and optional AI assistance. UI components depend on the engine and scoring module to render results and compute scores. + +```mermaid +graph LR +RF["redflags.js"] --> PROMPT["prompt.js"] +RF --> AI["ai.js"] +OP["OffersPage.jsx"] --> RF +OP --> SCORE["scoring.js"] +RV["ResultView.jsx"] --> RF +RV --> SCORE +``` + +**Diagram sources** +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [scoring.js](file://src/lib/scoring.js) + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [scoring.js](file://src/lib/scoring.js) + +## Performance Considerations +- Keep rule sets efficient by avoiding expensive regex operations where possible. +- Cache normalized text to prevent repeated preprocessing. +- Defer heavy computations (like AI calls) until necessary. +- Batch UI updates to reduce re-renders when presenting many findings. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- No red flags detected: Ensure input text is complete and uncorrupted; check normalization steps. +- False positives: Adjust keyword lists or thresholds; add negative test cases. +- UI not showing alerts: Verify data shape returned by the engine matches UI expectations. +- Performance degradation: Profile rule execution and optimize hot paths. + +Debugging aids: +- Enable verbose logging in development mode. +- Inspect intermediate findings before aggregation. +- Validate outputs against the expected schema. + +**Section sources** +- [redflags.test.js](file://src/lib/redflags.test.js) +- [redflags.js](file://src/lib/redflags.js) + +## Conclusion +The red flag detection system provides a robust, customizable framework for identifying risks in job offers. By combining rule-based detection with optional AI assistance and clear UI presentation, it helps users make informed decisions and take actionable next steps. Maintaining comprehensive tests and clear customization points ensures reliability and adaptability over time. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### API Reference Summary +- DetectRedFlags(input): Returns structured findings with category, severity, and details. +- ComputeOfferScore(findings): Computes an overall score influenced by red flag severities. +- RenderAlerts(findings): Presents findings in the UI with severity badges and recommendations. + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [scoring.js](file://src/lib/scoring.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Scoring Algorithms & Weighted Analysis.md b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Scoring Algorithms & Weighted Analysis.md new file mode 100644 index 0000000..ca0eb53 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Offer Management & Comparison/Scoring Algorithms & Weighted Analysis.md @@ -0,0 +1,341 @@ +# Scoring Algorithms & Weighted Analysis + + +**Referenced Files in This Document** +- [scoring.js](file://src/lib/scoring.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the scoring algorithms and weighted analysis system used to evaluate job offers. It covers how offer factors are identified, normalized, weighted, and combined into an overall score. It also documents configuration options for weights, normalization methods, calculation formulas, example calculations across different offer types, customization guidance, interpretation of final scores, and the test cases that validate accuracy. + +## Project Structure +The scoring logic is implemented as a set of focused modules: +- A dedicated scoring engine that computes factor scores, applies weights, normalizes inputs, and aggregates results. +- Supporting utilities for red flag detection, statistical helpers, and integration points with higher-level analysis flows. + +```mermaid +graph TB +subgraph "Scoring Core" +S["scoring.js"] +RF["redflags.js"] +ST["stats.js"] +end +subgraph "Integration" +AN["analyze.js"] +end +subgraph "Tests" +STS["scoring.test.js"] +RFT["redflags.test.js"] +SST["stats.test.js"] +end +AN --> S +S --> RF +S --> ST +STS --> S +RFT --> RF +SST --> ST +``` + +**Diagram sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +## Core Components +- Scoring Engine: Computes per-factor scores, applies configurable weights, normalizes values, and aggregates into an overall score. It exposes functions to compute raw factor contributions, apply weights, normalize inputs, and produce final outputs including breakdowns and flags. +- Red Flags Module: Detects negative signals (e.g., missing benefits, risky clauses) and contributes to penalty or flagging logic within the scoring pipeline. +- Stats Helpers: Provide utility functions for normalization, aggregation, and statistical operations used by the scoring engine. +- Integration Layer: The analysis module orchestrates data preparation, invokes scoring, and returns structured results for UI or downstream processing. + +Key responsibilities: +- Factor extraction from offer data +- Normalization of heterogeneous inputs +- Weight application and aggregation +- Red flag detection and impact on score +- Testable, deterministic computation with clear inputs/outputs + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) +- [analyze.js](file://src/lib/analyze.js) + +## Architecture Overview +The scoring workflow transforms raw offer attributes into a normalized, weighted score with detailed breakdowns and flags. + +```mermaid +sequenceDiagram +participant Caller as "Caller" +participant Analyzer as "analyze.js" +participant Scorer as "scoring.js" +participant RedFlags as "redflags.js" +participant Stats as "stats.js" +Caller->>Analyzer : "Analyze offer data" +Analyzer->>Scorer : "Compute scores(input, config)" +Scorer->>Stats : "Normalize inputs" +Scorer->>RedFlags : "Detect red flags" +RedFlags-->>Scorer : "Flag list" +Scorer->>Scorer : "Apply weights and aggregate" +Scorer-->>Analyzer : "Score + breakdown + flags" +Analyzer-->>Caller : "Final result" +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) + +## Detailed Component Analysis + +### Scoring Engine +Responsibilities: +- Accepts offer attributes and weight configuration +- Normalizes each factor to a common scale +- Applies weights to normalized factors +- Aggregates into an overall score +- Produces a detailed breakdown and red flags + +Inputs: +- Offer attributes (e.g., compensation components, benefits, role characteristics) +- Weight configuration object defining factor importance and optional thresholds + +Outputs: +- Overall score +- Per-factor scores +- Normalized factor values +- Red flags and their impacts + +Normalization: +- Uses helper utilities to map diverse inputs to a consistent range suitable for weighting and aggregation. + +Weighting and Aggregation: +- Multiplies normalized factor values by corresponding weights +- Aggregates using a configured method (e.g., weighted sum) to produce the final score + +Red Flags: +- Integrates with the red flags module to detect issues that may reduce the score or add warnings + +Customization: +- Weights can be adjusted per factor to reflect user priorities or company policies +- Optional parameters allow tuning normalization behavior and threshold-based penalties + +Example Calculation Flow: +- Normalize each factor +- Multiply by weights +- Sum weighted values +- Apply any red flag adjustments +- Return final score and breakdown + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) + +#### Class Diagram +```mermaid +classDiagram +class ScoringEngine { ++computeScores(offer, config) ++normalize(value, method) ++applyWeights(factors, weights) ++aggregate(values, method) ++getBreakdown() ++getFlags() +} +class RedFlagsModule { ++detect(offer) ++impact(flags) +} +class StatsHelpers { ++normalizeRange(values, min, max) ++weightedSum(values, weights) +} +ScoringEngine --> RedFlagsModule : "uses" +ScoringEngine --> StatsHelpers : "uses" +``` + +**Diagram sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [stats.js](file://src/lib/stats.js) + +### Red Flags Module +Responsibilities: +- Identify risk indicators in offer data +- Quantify potential negative impact on the score +- Provide actionable insights for users + +Common checks include: +- Missing or below-market compensation elements +- Absence of key benefits +- Contractual risks or unfavorable terms + +Impact: +- Adjusts final score or adds warning flags based on severity and frequency + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) +- [redflags.test.js](file://src/lib/redflags.test.js) + +### Stats Helpers +Responsibilities: +- Provide normalization functions to bring disparate inputs onto a common scale +- Implement aggregation utilities such as weighted sums +- Ensure numerical stability and edge-case handling + +Usage: +- Called by the scoring engine during normalization and aggregation phases + +**Section sources** +- [stats.js](file://src/lib/stats.js) +- [stats.test.js](file://src/lib/stats.test.js) + +### Integration Layer (Analysis) +Responsibilities: +- Prepare input data for scoring +- Invoke the scoring engine with appropriate configuration +- Format results for consumption by UI or other systems + +Flow: +- Receives raw offer data +- Calls scoring functions +- Returns structured output including score, breakdown, and flags + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +## Dependency Analysis +The scoring system has clear separation of concerns: +- Scoring depends on stats helpers for normalization/aggregation and red flags for risk detection. +- The analysis layer orchestrates calls to scoring and returns final results. +- Tests validate each component independently and in combination. + +```mermaid +graph LR +A["analyze.js"] --> B["scoring.js"] +B --> C["stats.js"] +B --> D["redflags.js"] +T1["scoring.test.js"] --> B +T2["redflags.test.js"] --> D +T3["stats.test.js"] --> C +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [redflags.js](file://src/lib/redflags.js) +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +## Performance Considerations +- Keep normalization and aggregation operations efficient; avoid unnecessary recomputation when inputs do not change. +- Cache intermediate normalized values if multiple aggregations are performed. +- Limit the number of red flag checks to only those relevant to the current offer type. +- Use vectorized operations where possible for batch scoring scenarios. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Unexpected low scores: Verify normalization ranges and ensure all required factors are present. Check red flags for negative impacts. +- Inconsistent results across runs: Confirm deterministic inputs and stable weight configurations. Validate that random or time-dependent inputs are not influencing scoring. +- Edge cases with zero or null values: Ensure normalization handles missing data gracefully and that weights for absent factors do not distort the final score. + +Validation approach: +- Unit tests assert expected outputs for representative inputs +- Boundary conditions are covered to ensure robustness +- Red flag detection is validated against known risky patterns + +**Section sources** +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) +- [stats.test.js](file://src/lib/stats.test.js) + +## Conclusion +The scoring system provides a flexible, configurable framework for evaluating job offers. By normalizing diverse inputs, applying customizable weights, and integrating red flag detection, it produces transparent, interpretable scores with detailed breakdowns. The modular design supports easy extension and maintenance, while comprehensive tests ensure reliability. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Scoring Criteria and Weight Configuration +- Factors: Compensation, benefits, role fit, growth opportunities, work-life balance, risk indicators +- Weights: Configurable per factor to reflect user preferences or organizational policies +- Normalization: Maps each factor to a common scale before weighting +- Aggregation: Combines weighted factors into an overall score + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) + +### Example Score Calculations +- Base salary-focused offer: Higher weight on compensation yields a strong overall score if normalized value is high +- Benefits-heavy offer: Elevated benefit weights improve the score even if base compensation is moderate +- Risky contract offer: Red flags reduce the score despite favorable compensation/benefits + +Note: Refer to test cases for concrete input/output examples and boundary conditions. + +**Section sources** +- [scoring.test.js](file://src/lib/scoring.test.js) +- [redflags.test.js](file://src/lib/redflags.test.js) + +### Interpretation of Final Scores +- Higher scores indicate more favorable offers based on configured weights and criteria +- Breakdown reveals which factors contributed positively or negatively +- Red flags highlight areas requiring attention or negotiation + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) + +### Customization Guidance +- Adjust weights to prioritize personal or company-specific criteria +- Modify normalization methods if domain knowledge suggests alternative scaling +- Extend red flag rules to capture additional risk indicators + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Core Features/Resume Scanner & Analysis.md b/.qoder/repowiki/en/content/Core Features/Resume Scanner & Analysis.md new file mode 100644 index 0000000..73dfdb2 --- /dev/null +++ b/.qoder/repowiki/en/content/Core Features/Resume Scanner & Analysis.md @@ -0,0 +1,459 @@ +# Resume Scanner & Analysis + + +**Referenced Files in This Document** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [samples.js](file://src/lib/samples.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the resume scanning and analysis feature, covering how users upload resumes, how the system parses and extracts content, and how it generates structured analysis results for downstream features. It also documents supported formats, validation rules, error handling, sample templates, integration points with the broader application ecosystem, and guidance on parsing accuracy and performance. + +## Project Structure +The resume scanning feature is implemented as a client-side flow with optional server-side AI assistance: +- Upload UI and user interactions are handled by React components. +- Parsing and extraction logic live in library modules. +- Scoring and red flag detection provide structured insights. +- Optional AI-based enhancement uses an AI proxy function. +- Results are displayed in a dedicated view and can be persisted via Supabase. + +```mermaid +graph TB +subgraph "Frontend" +A["ScanForm.jsx"] +B["ResultView.jsx"] +C["Tracker.jsx"] +end +subgraph "Libraries" +D["analyze.js"] +E["scoring.js"] +F["redflags.js"] +G["samples.js"] +H["prompt.js"] +I["ai.js"] +end +subgraph "Backend" +J["Supabase (DB)"] +K["AI Proxy Function"] +end +A --> D +A --> G +A --> H +D --> E +D --> F +D --> I +I --> K +B --> E +B --> F +C --> J +B --> J +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [samples.js](file://src/lib/samples.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [samples.js](file://src/lib/samples.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Core Components +- File upload interface: Provides drag-and-drop or file picker to accept resumes, validates file types and sizes, and prepares content for parsing. +- Parser and extractor: Converts uploaded files into normalized text, then extracts structured fields such as name, contact info, summary, skills, experience, education, and certifications. +- Analyzer: Applies scoring heuristics and red flag detection to produce actionable insights. +- AI enhancement (optional): Uses an AI proxy to refine extraction or generate summaries when enabled. +- Result display: Renders structured data, scores, and recommendations; allows saving to persistent storage. + +Key responsibilities: +- Input validation and format routing +- Text normalization and section segmentation +- Field extraction using patterns and heuristics +- Scoring and risk indicators +- Output serialization for downstream features + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [samples.js](file://src/lib/samples.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +## Architecture Overview +The resume pipeline consists of three stages: +- Ingestion: Accepts files, validates, and converts to text. +- Extraction: Segments content and extracts key fields. +- Analysis: Computes scores and flags, optionally enhanced by AI. + +```mermaid +sequenceDiagram +participant U as "User" +participant UI as "ScanForm.jsx" +participant P as "analyze.js" +participant S as "scoring.js" +participant R as "redflags.js" +participant AI as "ai.js -> AI Proxy" +participant V as "ResultView.jsx" +participant DB as "Supabase" +U->>UI : "Upload resume file" +UI->>P : "Parse and extract" +P-->>UI : "Structured resume object" +P->>S : "Compute scores" +P->>R : "Detect red flags" +P->>AI : "Optional AI enhancement" +AI-->>P : "Enhanced insights" +P-->>V : "Final analysis result" +V->>DB : "Persist if requested" +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### File Upload Interface (ScanForm) +Responsibilities: +- Present a file input supporting common resume formats. +- Validate file type and size before processing. +- Provide user feedback for errors and progress. +- Trigger parsing upon successful selection. + +Supported formats: +- PDF (.pdf) +- Word (.docx) +- Plain text (.txt) +- HTML (.html/.htm) + +Validation rules: +- Allowed MIME types and extensions +- Maximum file size limit +- Non-empty content after conversion + +Error handling: +- Invalid file type or corrupted file +- Exceeds size limit +- Conversion failures with clear messages + +Integration: +- Calls parser module to convert and extract +- Displays initial loading state while parsing completes + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +### Parser and Extractor (analyze.js) +Responsibilities: +- Convert different formats to normalized text. +- Segment sections (e.g., Summary, Experience, Education, Skills). +- Extract key fields using pattern matching and heuristics. +- Normalize dates, locations, and role titles. +- Produce a structured resume object suitable for analysis. + +Processing logic: +- Format-specific readers route to appropriate converters. +- Text normalization includes whitespace cleanup and encoding fixes. +- Section detection uses headings and layout cues. +- Field extraction applies regex patterns and contextual rules. +- De-duplication and conflict resolution for repeated entries. + +Output structure (high level): +- Personal information: name, email, phone, links +- Professional summary +- Work experience: roles, companies, durations, achievements +- Education: degrees, institutions, dates +- Skills: categorized lists +- Certifications and awards +- Metadata: source format, parsing confidence + +Parsing accuracy considerations: +- Higher accuracy for well-structured, machine-readable formats (PDF with selectable text, DOCX, TXT). +- Lower accuracy for scanned images or heavily styled layouts; OCR is not included in this implementation. +- Confidence scores per field indicate reliability. + +Optimization opportunities: +- Cache parsed results for identical inputs. +- Parallelize independent extractions where feasible. +- Use incremental updates for large documents. + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### Scoring Engine (scoring.js) +Responsibilities: +- Compute overall resume quality score. +- Evaluate completeness across sections. +- Measure relevance against target job descriptions when provided. +- Provide weighted sub-scores (experience, education, skills, formatting). + +Algorithm highlights: +- Weighted aggregation of component scores. +- Penalty for missing critical sections. +- Bonus signals for quantified achievements and recent activity. +- Normalization to consistent scale. + +Inputs: +- Structured resume object from analyzer. +- Optional job description or role profile. + +Outputs: +- Overall score +- Sub-scores and breakdown +- Improvement suggestions + +**Section sources** +- [scoring.js](file://src/lib/scoring.js) + +### Red Flag Detection (redflags.js) +Responsibilities: +- Identify potential issues such as employment gaps, inconsistent dates, or missing contact details. +- Detect formatting problems like excessive length or dense blocks. +- Surface warnings that may impact ATS compatibility. + +Rules: +- Date consistency checks across roles and education. +- Presence of essential fields. +- Length and readability thresholds. +- Common pitfalls flagged with explanations. + +Outputs: +- List of flags with severity levels +- Actionable remediation tips + +**Section sources** +- [redflags.js](file://src/lib/redflags.js) + +### Sample Templates (samples.js) +Responsibilities: +- Provide example resume structures for testing and demos. +- Offer baseline templates to validate parsing and scoring. +- Support quick start without uploading real files. + +Usage: +- Load sample data into the analyzer. +- Compare outputs against expected fields. +- Demonstrate scoring and red flag behavior. + +**Section sources** +- [samples.js](file://src/lib/samples.js) + +### Prompt Engineering (prompt.js) +Responsibilities: +- Define prompts used by AI enhancement steps. +- Standardize instructions for extraction refinement and summarization. +- Maintain versioning and environment-specific overrides. + +Integration: +- Consumed by AI module when AI features are enabled. +- Supports parameterized prompts for different resume types. + +**Section sources** +- [prompt.js](file://src/lib/prompt.js) + +### AI Enhancement (ai.js) +Responsibilities: +- Optionally call AI proxy to improve extraction or generate summaries. +- Handle request/response lifecycle and retries. +- Map AI responses back into the structured resume object. + +Workflow: +- Build prompt based on current resume context. +- Send request to AI proxy function. +- Parse response and merge enhancements. +- Fallback to deterministic extraction when AI is unavailable. + +Security and privacy: +- Avoid sending sensitive personal data unless explicitly permitted. +- Log minimal metadata for diagnostics. + +**Section sources** +- [ai.js](file://src/lib/ai.js) + +### Results Display (ResultView) +Responsibilities: +- Render structured resume data, scores, and flags. +- Allow exporting or sharing results. +- Provide drill-down views for each section. + +Integration: +- Reads analysis output from analyzer. +- Persists results to Supabase if user opts in. +- Feeds data into other app features (e.g., tracking, coaching). + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### Persistence and Tracking (Tracker + Supabase) +Responsibilities: +- Save analysis results and metadata to database. +- Track historical scans and improvements over time. +- Sync across devices if enabled. + +Schema alignment: +- Tables store resumes, analyses, and related entities. +- Constraints ensure referential integrity. + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Dependency Analysis +Internal dependencies: +- ScanForm depends on analyze and samples for ingestion and demo flows. +- analyze orchestrates scoring and red flags, and optionally ai. +- ResultView consumes outputs from analyze, scoring, and red flags. +- Tracker integrates with supabase for persistence. + +External dependencies: +- Supabase for storage and sync. +- AI proxy function for optional enhancement. + +```mermaid +graph LR +ScanForm["ScanForm.jsx"] --> Analyze["analyze.js"] +Analyze --> Scoring["scoring.js"] +Analyze --> RedFlags["redflags.js"] +Analyze --> AI["ai.js"] +AI --> AIProxy["AI Proxy Function"] +ResultView["ResultView.jsx"] --> Scoring +ResultView --> RedFlags +Tracker["Tracker.jsx"] --> Supabase["supabase.js"] +Supabase --> Schema["001_schema.sql"] +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Performance Considerations +- Prefer lightweight formats (TXT, DOCX) for faster parsing. +- Limit maximum file size to reduce memory usage. +- Cache parsed results for identical inputs to avoid reprocessing. +- Defer AI enhancement until necessary to minimize latency. +- Stream results incrementally in the UI for better perceived performance. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Unsupported file type: Ensure the file extension and MIME type match allowed formats. +- Corrupted or password-protected files: Re-export the document to a plain, unprotected format. +- Empty or unreadable text: Some PDFs are image-only; convert to selectable text first. +- Missing fields: Check for non-standard headings or unusual layouts; use sample templates to compare. +- AI enhancement failures: Verify network connectivity and retry; fall back to deterministic extraction. + +Diagnostic steps: +- Inspect parsing confidence scores per field. +- Review red flags for structural issues. +- Validate schema constraints when persisting results. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [redflags.js](file://src/lib/redflags.js) +- [ai.js](file://src/lib/ai.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Conclusion +The resume scanner and analysis feature provides a robust pipeline for ingesting, parsing, extracting, and analyzing resumes across multiple formats. It combines deterministic heuristics with optional AI enhancement to deliver structured data, scores, and actionable insights. The modular architecture supports extensibility, reliable error handling, and integration with persistence and downstream features. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Supported Formats and Examples +- PDF: Selectable text preferred; avoid scanned images. +- DOCX: High accuracy due to structured markup. +- TXT: Simplest format; relies on content clarity. +- HTML: Useful for web-published resumes. + +Examples: +- Use sample templates to validate parsing and scoring behavior. + +**Section sources** +- [samples.js](file://src/lib/samples.js) + +### Validation Rules Summary +- Allowed formats and extensions +- Maximum file size +- Required fields presence checks +- Date consistency and range validation +- Formatting and readability thresholds + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [redflags.js](file://src/lib/redflags.js) + +### Integration Points +- Upstream: User uploads via ScanForm. +- Downstream: Results consumed by ResultView, Tracker, and other app features. +- External: Supabase for storage; AI proxy for optional enhancement. + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [ai.js](file://src/lib/ai.js) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Data Management/Cloud Synchronization.md b/.qoder/repowiki/en/content/Data Management/Cloud Synchronization.md new file mode 100644 index 0000000..07c1bce --- /dev/null +++ b/.qoder/repowiki/en/content/Data Management/Cloud Synchronization.md @@ -0,0 +1,353 @@ +# Cloud Synchronization + + +**Referenced Files in This Document** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the cloud synchronization features in ApplyGuard PH with a focus on real-time sync using Supabase subscriptions, conflict resolution strategies, and data consistency guarantees. It covers sync triggers, batch operations, incremental updates, offline-first behavior, queue management for failed operations, automatic retry logic, data transformation pipelines between local and cloud formats, field mappings, validation rules, troubleshooting techniques, and performance optimization strategies for large datasets. + +## Project Structure +The synchronization layer is implemented primarily under src/lib with supporting Supabase configuration and schema definitions: +- Sync orchestration and state machine: src/lib/sync.js +- Cloud API client and helpers: src/lib/cloud.js +- Supabase client initialization and utilities: src/lib/supabase.js +- Local storage abstraction (offline-first): src/lib/storage.js +- Database schema and RLS policies: supabase/migrations/001_schema.sql +- Shared HTTP helper for serverless functions: supabase/functions/_shared/http.ts + +```mermaid +graph TB +subgraph "Frontend" +A["sync.js
Orchestrator"] +B["cloud.js
Cloud Client"] +C["supabase.js
Client Init"] +D["storage.js
Local Store"] +end +subgraph "Supabase" +E["Realtime Subscriptions"] +F["Postgres Tables"] +G["Edge Functions"] +end +A --> B +B --> C +C --> E +C --> F +A --> D +B --> G +``` + +**Diagram sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Core Components +- Sync Orchestrator: Coordinates lifecycle, manages queues, handles retries, and applies conflict resolution. +- Cloud Client: Encapsulates Supabase calls, batching, and error handling. +- Supabase Client: Initializes connection, configures realtime subscriptions, and exposes typed queries. +- Storage Abstraction: Provides an offline-first key-value store with change tracking and persistence. +- Schema and Policies: Defines tables, constraints, indexes, and row-level security to ensure consistency and access control. +- Shared HTTP Helper: Utility used by serverless functions for outbound requests. + +Key responsibilities: +- Real-time event ingestion and reconciliation +- Incremental updates via timestamps or version fields +- Batched writes to reduce network overhead +- Queueing and retry with backoff for transient failures +- Conflict detection and deterministic resolution + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Architecture Overview +The system follows an offline-first architecture with bidirectional sync over Supabase Realtime. The orchestrator maintains a local queue of pending mutations and reconciles changes from both local edits and remote events. + +```mermaid +sequenceDiagram +participant UI as "UI Layer" +participant Sync as "Sync Orchestrator" +participant Store as "Local Storage" +participant Cloud as "Cloud Client" +participant SB as "Supabase Client" +participant RT as "Realtime" +participant DB as "Postgres" +UI->>Sync : "Create/Update/Delete entity" +Sync->>Store : "Persist locally" +Sync->>Sync : "Enqueue mutation" +Sync->>Cloud : "Apply mutation" +Cloud->>SB : "Write to DB" +SB-->>RT : "Emit change event" +RT-->>SB : "Subscribe to table" +SB-->>Sync : "Remote change event" +Sync->>Sync : "Reconcile and resolve conflicts" +Sync->>Store : "Update local state" +``` + +**Diagram sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Sync Orchestrator +Responsibilities: +- Manage sync lifecycle (start, stop, pause/resume) +- Maintain a queue of pending operations with metadata (id, type, payload, timestamp, attempts) +- Process queue items with exponential backoff and jitter +- Subscribe to Supabase Realtime channels per table/entity +- Reconcile incoming remote changes against local state +- Enforce idempotency and deduplicate operations +- Expose hooks/events for UI feedback + +Key behaviors: +- Trigger mechanisms: + - User actions trigger enqueue and immediate apply attempt + - Network recovery triggers queue drain + - Periodic reconciliation ensures drift correction +- Batch operations: + - Coalesce multiple mutations within a time window into a single batch write + - Preserve ordering within batches +- Incremental updates: + - Use server-side timestamps or version fields to detect changes + - Fetch only deltas when possible +- Conflict resolution: + - Strategy selection based on entity type (e.g., last-writer-wins, merge-by-field, server-authoritative) + - Deterministic tie-breakers (e.g., lexicographic ID comparison) +- Data consistency guarantees: + - At-least-once delivery with idempotent keys + - Transaction-like semantics via ordered processing and rollback on failure + - Eventual consistency across devices + +```mermaid +flowchart TD +Start(["Start Sync"]) --> Init["Initialize clients and subscriptions"] +Init --> Listen["Listen for local changes"] +Listen --> Enqueue["Enqueue mutation"] +Enqueue --> TryApply{"Network available?"} +TryApply --> |Yes| Apply["Apply to cloud"] +TryApply --> |No| Wait["Wait for connectivity"] +Apply --> Result{"Success?"} +Result --> |Yes| Ack["Ack and update local"] +Result --> |No| Retry["Retry with backoff"] +Retry --> MaxAttempts{"Exceeded max attempts?"} +MaxAttempts --> |No| TryApply +MaxAttempts --> |Yes| Fail["Mark failed and notify"] +Ack --> Listen +Fail --> Listen +Listen --> RemoteEvent["Receive remote event"] +RemoteEvent --> Reconcile["Reconcile with local"] +Reconcile --> UpdateLocal["Update local store"] +UpdateLocal --> Listen +``` + +**Diagram sources** +- [src/lib/sync.js](file://src/lib/sync.js) + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) + +### Cloud Client +Responsibilities: +- Wrap Supabase client methods for reads/writes +- Implement batching for create/update/delete operations +- Normalize payloads and map to cloud schema +- Handle errors and translate to user-friendly messages +- Provide utilities for pagination and cursor-based fetching + +Key behaviors: +- Batch writes: + - Group mutations by table and operation type + - Respect size limits and timeouts +- Error handling: + - Distinguish transient vs permanent errors + - Surface actionable diagnostics +- Field mapping: + - Transform local model fields to cloud schema fields + - Validate required fields before sending + +**Section sources** +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) + +### Supabase Client +Responsibilities: +- Initialize Supabase instance with environment configuration +- Configure realtime subscriptions per table +- Provide typed query helpers +- Manage auth context and session handling + +Key behaviors: +- Realtime subscriptions: + - Filter by user or tenant scope + - Handle reconnection and channel lifecycle +- Query helpers: + - Support filtering, sorting, and pagination + - Optimize for incremental fetches + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) + +### Storage Abstraction +Responsibilities: +- Provide a persistent key-value store for offline-first behavior +- Track change history and versions +- Support atomic transactions for multi-key updates +- Export/import snapshots for migration or backup + +Key behaviors: +- Offline-first reads: + - Serve from local store immediately + - Optionally mark entries as stale until refreshed +- Change tracking: + - Record timestamps and operation types + - Enable delta computation for sync + +**Section sources** +- [src/lib/storage.js](file://src/lib/storage.js) + +### Schema and Policies +Responsibilities: +- Define tables, columns, constraints, and indexes +- Enforce row-level security policies for multi-user isolation +- Ensure referential integrity and data quality + +Key considerations: +- Include server-side timestamps and version fields +- Add unique constraints to support idempotent upserts +- Index frequently queried fields for performance + +**Section sources** +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Shared HTTP Helper +Responsibilities: +- Provide common HTTP request utilities for serverless functions +- Standardize headers, error formatting, and logging + +Usage: +- Used by edge functions that interact with external services during sync workflows + +**Section sources** +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Dependency Analysis +The following diagram shows how components depend on each other and on Supabase services. + +```mermaid +graph LR +Sync["sync.js"] --> Cloud["cloud.js"] +Sync --> Storage["storage.js"] +Cloud --> Supabase["supabase.js"] +Supabase --> Realtime["Supabase Realtime"] +Supabase --> Postgres["Postgres"] +Cloud --> EdgeFuncs["Edge Functions"] +EdgeFuncs --> Http["http.ts"] +``` + +**Diagram sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Performance Considerations +- Batch writes: + - Coalesce mutations within short windows to reduce round trips + - Limit batch sizes to avoid timeouts and memory pressure +- Incremental updates: + - Use server timestamps/version fields to fetch only changed rows + - Prefer cursor-based pagination for large result sets +- Indexing: + - Add indexes on foreign keys, filters, and sort fields + - Avoid over-indexing; monitor query plans +- Connection resilience: + - Implement exponential backoff with jitter for retries + - Use circuit breaker patterns for repeated failures +- Memory usage: + - Stream large datasets instead of loading all at once + - Clear processed queue entries promptly +- Realtime efficiency: + - Subscribe only to relevant channels and filter by user/tenant + - Debounce high-frequency events if necessary + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Realtime not receiving events: + - Verify subscription channels and filters + - Check network connectivity and firewall rules + - Confirm RLS policies allow read access +- Conflicts not resolving: + - Inspect conflict strategy and tie-breaker logic + - Validate server timestamps and version fields +- Queue backlog: + - Monitor queue length and retry counts + - Increase batch size cautiously and tune backoff parameters +- Slow initial sync: + - Use incremental fetch with cursors + - Preload critical entities and lazy-load others +- Data inconsistencies: + - Run reconciliation jobs periodically + - Audit logs for out-of-order events + +Debugging techniques: +- Enable detailed logging around enqueue, apply, and reconcile phases +- Snapshot local store state before and after reconciliation +- Instrument metrics for queue depth, retry rates, and latency +- Use Supabase dashboard to inspect realtime events and query performance + +**Section sources** +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Conclusion +ApplyGuard PH’s cloud synchronization leverages an offline-first design with robust queueing, batching, and incremental updates. Supabase Realtime enables near-real-time collaboration while maintaining data consistency through careful conflict resolution and idempotent operations. By tuning batch sizes, indexing strategically, and monitoring queue health, the system scales effectively even with large datasets. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Data Management/Data Management.md b/.qoder/repowiki/en/content/Data Management/Data Management.md new file mode 100644 index 0000000..45f5256 --- /dev/null +++ b/.qoder/repowiki/en/content/Data Management/Data Management.md @@ -0,0 +1,409 @@ +# Data Management + + +**Referenced Files in This Document** +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [config.toml](file://supabase/config.toml) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the data management system for ApplyGuard PH, focusing on local storage, cloud synchronization, conflict resolution, CSV import/export, data sharing, backup and restore, data models, validation rules, transformation pipelines, migration handling, version compatibility, integrity checks, and performance considerations for large datasets. It is intended for both technical and non-technical readers to understand how data flows through the application and how consistency and reliability are maintained across devices and sessions. + +## Project Structure +The data management layer is implemented primarily under src/lib with supporting configuration and schema definitions under supabase. The key modules include: +- Local persistence and state orchestration +- Cloud client and sync engine +- CSV I/O utilities +- Sharing mechanisms +- Supabase client configuration +- Database schema and server-side configuration + +```mermaid +graph TB +subgraph "Frontend" +Store["Store (state)"] +Storage["Local Storage Adapter"] +SyncEngine["Sync Engine"] +CloudClient["Cloud Client"] +CSV["CSV Import/Export"] +Share["Data Sharing"] +end +subgraph "Backend" +Supabase["Supabase Client"] +DB[(Database Schema)] +Config["Server Config"] +end +Store --> Storage +Store --> SyncEngine +SyncEngine --> CloudClient +CloudClient --> Supabase +Supabase --> DB +CSV --> Store +Share --> Store +Config --> Supabase +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [config.toml](file://supabase/config.toml) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [config.toml](file://supabase/config.toml) + +## Core Components +- Local storage adapter: Provides a consistent interface for reading/writing application data to persistent storage, including serialization, deserialization, and error handling. +- Sync engine: Coordinates bidirectional synchronization between local state and remote cloud state, managing change detection, batching, and conflict resolution. +- Cloud client: Encapsulates communication with the backend via the Supabase client, handling authentication context, retries, and error mapping. +- CSV utilities: Implement parsing and generation of CSV files for import/export, including header normalization, type coercion, and validation. +- Sharing module: Enables exporting/importing subsets or full snapshots of data for collaboration or archival purposes. +- Supabase client: Centralized configuration for database access, including environment-based settings and connection options. +- Store: Application-level state container that orchestrates interactions among storage, sync, and UI updates. + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview +The data architecture follows a layered approach: +- Presentation layer consumes state from the store. +- Store coordinates operations across storage, sync, and external services. +- Sync engine mediates between local changes and remote state using the cloud client. +- Cloud client uses the Supabase client to interact with the database defined by migrations. + +```mermaid +sequenceDiagram +participant UI as "UI Layer" +participant Store as "Store" +participant Storage as "Local Storage" +participant Sync as "Sync Engine" +participant Cloud as "Cloud Client" +participant Supa as "Supabase Client" +participant DB as "Database" +UI->>Store : Request data / Dispatch action +Store->>Storage : Read local snapshot +alt Local cache miss or stale +Store->>Sync : Initiate sync +Sync->>Cloud : Fetch remote state +Cloud->>Supa : Query records +Supa-->>Cloud : Records + metadata +Cloud-->>Sync : Remote dataset +Sync->>Sync : Resolve conflicts +Sync->>Storage : Persist resolved state +end +Store-->>UI : Updated state +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +## Detailed Component Analysis + +### Local Storage Implementation +Responsibilities: +- Provide typed read/write operations for application entities. +- Serialize/deserialize data safely, handling versioning and schema evolution. +- Offer transaction-like semantics where possible to maintain consistency. +- Surface errors consistently for upstream handling. + +Key behaviors: +- Version-aware storage keys and migration hooks. +- Defensive parsing with fallbacks to defaults on corruption. +- Optional compression or chunking strategies for large payloads. + +Validation and integrity: +- Pre-write validation against expected schemas. +- Post-read verification with checksums or structural checks when applicable. + +Optimization: +- Batched writes to reduce I/O overhead. +- Lazy loading of heavy datasets. + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### Cloud Synchronization Architecture +Responsibilities: +- Maintain eventual consistency between local and remote datasets. +- Detect and merge changes while preserving user intent. +- Handle network failures, partial responses, and rate limits. + +Conflict resolution strategy: +- Field-level merging based on timestamps or explicit version vectors. +- Last-writer-wins for non-collaborative fields; manual resolution prompts for conflicting edits. +- De-duplication by stable identifiers. + +Operational flow: +- Change tracking at the store level. +- Incremental sync with delta uploads. +- Conflict detection and resolution pipeline before persisting merged results. + +**Section sources** +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) + +### CSV Import/Export Functionality +Import pipeline: +- Parse raw CSV into structured rows. +- Normalize headers and map to internal data model. +- Validate each row and collect errors without aborting the entire batch. +- Transform values (e.g., dates, booleans) according to schema. +- Upsert into local store and optionally push to cloud. + +Export pipeline: +- Select subset or full dataset. +- Serialize to CSV with deterministic ordering and consistent formatting. +- Provide download triggers and progress feedback. + +Error handling: +- Row-level error reporting with line numbers and field names. +- Partial success semantics with rollback or quarantine for invalid rows. + +**Section sources** +- [csv.js](file://src/lib/csv.js) + +### Data Sharing Mechanisms +Capabilities: +- Export a shareable snapshot (CSV or compact format). +- Import shared data into another instance with conflict checks. +- Support selective sharing of specific entities or filtered views. + +Security and privacy: +- Optional encryption for exported artifacts. +- Clear guidance on sensitive data exposure during sharing. + +**Section sources** +- [share.js](file://src/lib/share.js) + +### Backup and Restore Procedures +Backup: +- Full export of local state to a portable artifact. +- Incremental backups keyed by timestamps or version IDs. + +Restore: +- Validate artifact integrity before applying. +- Merge or replace existing data based on policy. +- Rollback plan if restore fails mid-way. + +**Section sources** +- [share.js](file://src/lib/share.js) +- [csv.js](file://src/lib/csv.js) + +### Data Models, Validation Rules, and Transformation Pipelines +Data models: +- Entities defined by the database schema and mirrored in the frontend store. +- Stable identifiers used for cross-device reconciliation. + +Validation rules: +- Required fields, types, ranges, and referential constraints enforced locally and on the server. +- Custom business rules applied during import and sync merges. + +Transformation pipelines: +- Normalize inputs (e.g., trimming, casing). +- Coerce types and compute derived fields. +- Enrich data with computed attributes prior to persistence. + +**Section sources** +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) + +### Data Migration Handling, Version Compatibility, and Integrity Checks +Migration handling: +- Versioned storage keys and migration functions executed on startup. +- Backward-compatible reads with graceful degradation. + +Version compatibility: +- Feature flags and schema versions gate new behavior. +- Safe rollouts with opt-out paths for corrupted states. + +Integrity checks: +- Structural validation after load. +- Cross-entity consistency checks (e.g., foreign key references). +- Checksums for critical artifacts. + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + +### Supabase Integration +Responsibilities: +- Centralized client configuration and environment setup. +- Authentication context propagation and session management. +- Typed queries and mutations aligned with the database schema. + +Configuration: +- Endpoint URLs, project identifiers, and feature toggles managed via configuration. + +**Section sources** +- [supabase.js](file://src/lib/supabase.js) +- [config.toml](file://supabase/config.toml) + +## Dependency Analysis +The following diagram shows core dependencies among data management modules: + +```mermaid +graph LR +Store["store.jsx"] --> Storage["storage.js"] +Store --> Sync["sync.js"] +Sync --> Cloud["cloud.js"] +Cloud --> Supabase["supabase.js"] +CSV["csv.js"] --> Store +Share["share.js"] --> Store +Supabase --> Schema["001_schema.sql"] +Supabase --> Config["config.toml"] +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [config.toml](file://supabase/config.toml) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [csv.js](file://src/lib/csv.js) +- [share.js](file://src/lib/share.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) +- [config.toml](file://supabase/config.toml) + +## Performance Considerations +- Local storage: + - Use batched writes and avoid frequent small updates. + - Employ lazy loading and pagination for large lists. + - Compress or partition large datasets if supported by the storage adapter. +- Sync: + - Prefer incremental deltas over full resyncs. + - Debounce rapid successive changes to coalesce sync requests. + - Implement retry with exponential backoff and circuit breakers for unstable networks. +- CSV: + - Stream processing for very large imports/exports to minimize memory usage. + - Pre-validate and normalize headers to reduce reprocessing. +- Database: + - Leverage indexes defined in the schema for common query patterns. + - Use server-side filtering and projection to reduce payload sizes. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Corrupted local state: + - Trigger integrity checks and rebuild from last known good snapshot. + - Reset to defaults for specific entities if necessary. +- Sync conflicts: + - Review conflict logs and apply recommended resolution policies. + - Force refresh from remote when local state is unreliable. +- CSV import failures: + - Inspect row-level error reports and correct malformed entries. + - Ensure header mappings match the current schema version. +- Network errors: + - Verify Supabase configuration and credentials. + - Retry failed operations with backoff and monitor rate limits. + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [csv.js](file://src/lib/csv.js) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +ApplyGuard PH’s data management system combines robust local persistence, reliable cloud synchronization, and flexible import/export capabilities. By enforcing clear validation rules, implementing thoughtful conflict resolution, and providing migration and integrity safeguards, the system ensures data consistency and resilience across devices and sessions. Performance-oriented practices such as batching, streaming, and indexing further support scalability for large datasets. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Data Flow Sequence for Import/Export +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "UI" +participant CSV as "CSV Module" +participant Store as "Store" +participant Storage as "Local Storage" +participant Sync as "Sync Engine" +participant Cloud as "Cloud Client" +participant Supa as "Supabase Client" +participant DB as "Database" +User->>UI : Choose Import/Export +alt Import +UI->>CSV : Load file and parse +CSV->>CSV : Validate and transform rows +CSV->>Store : Submit validated records +Store->>Storage : Persist locally +Store->>Sync : Queue for sync +Sync->>Cloud : Push changes +Cloud->>Supa : Write to DB +Supa-->>Cloud : Ack +Cloud-->>Sync : Success +Sync-->>Store : Update state +Store-->>UI : Show result +else Export +UI->>Store : Request dataset +Store->>Storage : Read snapshot +Store-->>UI : Dataset +UI->>CSV : Generate CSV +CSV-->>User : Download file +end +``` + +**Diagram sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Data Management/Data Sharing & Clipboard.md b/.qoder/repowiki/en/content/Data Management/Data Sharing & Clipboard.md new file mode 100644 index 0000000..7be1c99 --- /dev/null +++ b/.qoder/repowiki/en/content/Data Management/Data Sharing & Clipboard.md @@ -0,0 +1,333 @@ +# Data Sharing & Clipboard + + +**Referenced Files in This Document** +- [share.js](file://src/lib/share.js) +- [share.test.js](file://src/lib/share.test.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains how ApplyGuard PH shares application data and integrates with the system clipboard. It covers: +- How to share a view via URL +- How to copy results to the clipboard +- How to generate shareable reports +- URL structure for shared views +- Data encoding/decoding processes +- Access controls and security considerations +- Expiration policies and privacy controls +- Cross-platform compatibility patterns +- Examples of sharing workflows and integration with external applications + +## Project Structure +The sharing and clipboard features are implemented as small, focused modules under src/lib and integrated into the UI through components and state management. + +```mermaid +graph TB +subgraph "UI Layer" +RV["ResultView.jsx"] +end +subgraph "State & Storage" +ST["store.jsx"] +SS["storage.js"] +end +subgraph "Sharing & Clipboard" +SH["share.js"] +CL["clipboard.js"] +end +RV --> SH +RV --> CL +RV --> ST +ST --> SS +SH --> SS +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) + +## Core Components +- Share module (URL-based sharing): Encodes current analysis/view state into a compact representation suitable for URLs and decodes incoming shared links to restore the view. +- Clipboard module: Provides cross-platform helpers to write formatted text to the system clipboard and read from it when needed. +- ResultView component: Orchestrates user actions such as “Share” and “Copy to Clipboard,” invoking the appropriate modules. +- Store and storage utilities: Provide access to the current analysis state and persistence mechanisms used by sharing flows. + +Key responsibilities: +- share.js: URL generation, decoding, validation, and optional expiration handling. +- clipboard.js: Clipboard API usage, fallbacks, and formatting for human-readable outputs. +- ResultView.jsx: UI triggers and feedback for sharing/copying actions. +- store.jsx and storage.js: State access and persistence that feed into share payloads. + +**Section sources** +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +## Architecture Overview +The sharing architecture separates concerns between UI interactions, state serialization, and platform integrations. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "ResultView.jsx" +participant Share as "share.js" +participant Clip as "clipboard.js" +participant Store as "store.jsx" +participant Storage as "storage.js" +User->>UI : Click "Share" +UI->>Store : Read current analysis state +Store-->>UI : State snapshot +UI->>Share : encodeForUrl(state) +Share->>Storage : Optional persistence (if required) +Share-->>UI : Shared URL +UI-->>User : Show URL / Open share dialog +User->>UI : Click "Copy to Clipboard" +UI->>Clip : formatReport(state) +Clip-->>UI : Success/Failure +UI-->>User : Toast or status feedback +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +## Detailed Component Analysis + +### Share Module (URL-Based Sharing) +Responsibilities: +- Encode the current view/state into a URL-safe payload +- Decode incoming shared URLs to reconstruct the view +- Validate inputs and handle malformed or expired links +- Optionally persist shared snapshots for longer-lived sharing + +```mermaid +flowchart TD +Start(["Start"]) --> GetState["Read current state from store"] +GetState --> BuildPayload["Build minimal payload"] +BuildPayload --> Encode["Encode payload for URL"] +Encode --> DecidePersist{"Need server-side persistence?"} +DecidePersist --> |Yes| Persist["Persist snapshot and get ID"] +DecidePersist --> |No| SkipPersist["Skip persistence"] +Persist --> BuildUrl["Build final URL with parameters"] +SkipPersist --> BuildUrl +BuildUrl --> ReturnUrl["Return URL"] +ReturnUrl --> End(["End"]) +``` + +**Diagram sources** +- [share.js](file://src/lib/share.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +Security and privacy considerations: +- Avoid including sensitive fields in URL payloads; sanitize or omit PII before encoding. +- If using server-side persistence, enforce access controls and short expiration windows. +- Validate and normalize decoded payloads to prevent injection or unexpected behavior. + +Expiration policy guidance: +- Prefer short TTL for shared snapshots stored on the server. +- For client-only sharing (no persistence), rely on URL length limits and browser behavior. + +**Section sources** +- [share.js](file://src/lib/share.js) +- [share.test.js](file://src/lib/share.test.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +### Clipboard Integration +Responsibilities: +- Generate formatted text for sharing (e.g., summary report) +- Write to the system clipboard using modern APIs with graceful fallbacks +- Handle errors and provide user feedback + +```mermaid +flowchart TD +Entry(["Copy to Clipboard"]) --> Format["Format report text from state"] +Format --> TryModern{"Clipboard API available?"} +TryModern --> |Yes| WriteModern["Write text via Clipboard API"] +TryModern --> |No| Fallback["Fallback: create temporary textarea and execCommand"] +WriteModern --> Done["Success"] +Fallback --> FallbackDone{"Fallback succeeded?"} +FallbackDone --> |Yes| Done +FallbackDone --> |No| Error["Show error toast"] +Done --> Exit(["Exit"]) +Error --> Exit +``` + +Cross-platform notes: +- Use the modern Clipboard API where available. +- Provide a fallback path for older browsers or restricted contexts. +- Ensure text is plain or minimally formatted to maximize compatibility across apps. + +**Diagram sources** +- [clipboard.js](file://src/lib/clipboard.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +**Section sources** +- [clipboard.js](file://src/lib/clipboard.js) +- [ResultView.jsx](file://src/components/ResultView.jsx) + +### ResultView Integration +Responsibilities: +- Trigger share and copy actions based on user input +- Display success/error feedback via toasts or inline messages +- Coordinate with store to obtain the latest state for encoding/formatting + +```mermaid +sequenceDiagram +participant U as "User" +participant V as "ResultView.jsx" +participant S as "share.js" +participant C as "clipboard.js" +participant St as "store.jsx" +U->>V : Tap "Share" +V->>St : Get current state +St-->>V : State +V->>S : Create share URL +S-->>V : URL +V-->>U : Show URL / open share sheet +U->>V : Tap "Copy Report" +V->>C : Format and copy text +C-->>V : Status +V-->>U : Feedback +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis +High-level dependencies among sharing-related modules: + +```mermaid +graph LR +RV["ResultView.jsx"] --> SH["share.js"] +RV --> CL["clipboard.js"] +RV --> ST["store.jsx"] +SH --> SS["storage.js"] +CL --> RV +ST --> SS +``` + +Observations: +- Low coupling: share.js and clipboard.js are independent utilities invoked by the UI layer. +- State access is centralized via store.jsx, reducing duplication. +- Persistence is abstracted behind storage.js, enabling future changes without touching UI. + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) + +## Performance Considerations +- Keep URL payloads minimal to avoid truncation and improve load times. +- Defer heavy formatting until the user explicitly requests a copy action. +- Cache encoded payloads briefly if the same share operation is repeated frequently. +- Avoid synchronous clipboard operations on main thread in constrained environments; use async APIs where available. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Clipboard permission denied: + - Ensure the action is triggered by a user gesture. + - Fall back to a temporary element approach if the Clipboard API is unavailable. +- Shared link not restoring state: + - Verify payload schema and versioning; ensure backward-compatible decoding. + - Check for missing or invalid parameters and log diagnostic details. +- Long URLs truncated: + - Reduce payload size by excluding non-essential fields. + - Consider server-side persistence with short-lived IDs for large datasets. +- Mobile-specific behaviors: + - Some platforms restrict direct URL pasting; prefer native share sheets when available. + +**Section sources** +- [share.test.js](file://src/lib/share.test.js) +- [clipboard.js](file://src/lib/clipboard.js) + +## Conclusion +ApplyGuard PH’s sharing and clipboard features are modular and user-centric. The share module focuses on robust URL encoding/decoding and optional persistence with clear security boundaries, while the clipboard module ensures broad compatibility and reliable user feedback. Together with the UI orchestration in ResultView and state management in store.jsx and storage.js, these components enable safe, efficient, and cross-platform data sharing experiences. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### URL Structure for Shared Views +- Base domain/path: Provided by the hosting environment. +- Query parameters: + - v: Version of the payload schema + - d: Encoded data payload (compact, URL-safe) + - e: Optional expiration timestamp (server-side persisted only) +- Example pattern: https://app.example.com/share?v=1&d=&e= + +Notes: +- Do not include sensitive identifiers in the URL. +- Validate and sanitize all parameters on decode. + +[No sources needed since this section provides general guidance] + +### Security and Privacy Controls +- Minimize data in URLs; prefer server-side snapshots with short TTL for larger payloads. +- Enforce access controls on any persisted snapshots. +- Redact or hash sensitive fields before encoding. +- Log and monitor failed decode attempts for abuse detection. + +[No sources needed since this section provides general guidance] + +### Expiration Policies +- Client-only sharing: No server expiry; rely on URL length and browser behavior. +- Server-backed sharing: Set short TTL (e.g., minutes to hours) and auto-cleanup jobs. + +[No sources needed since this section provides general guidance] + +### External Application Integration +- Paste shared URL into another device’s browser to restore the view. +- Copy formatted report to clipboard and paste into email, chat, or documentation tools. +- On mobile, use the native share sheet to distribute the URL directly to messaging apps. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Data Management/Import & Export.md b/.qoder/repowiki/en/content/Data Management/Import & Export.md new file mode 100644 index 0000000..6368343 --- /dev/null +++ b/.qoder/repowiki/en/content/Data Management/Import & Export.md @@ -0,0 +1,375 @@ +# Import & Export + + +**Referenced Files in This Document** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the CSV import and export functionality in ApplyGuard PH. It covers: +- CSV format specifications and field mappings +- Data validation rules and supported data types +- Bulk import operations, error handling for malformed data, and progress tracking +- Export capabilities including filtering, formatting options, and file generation +- Security considerations for file uploads and data sanitization +- Examples of valid CSV structures and common import scenarios + +The implementation is primarily located in the client-side library that parses and generates CSV files, with integration points into application state and persistence layers. + +## Project Structure +CSV-related logic resides under the client library and integrates with the app’s store and persistence layer. The following diagram shows how the CSV module fits within the application. + +```mermaid +graph TB +subgraph "Client" +App["App.jsx"] +Store["store.jsx"] +CsvLib["lib/csv.js"] +Supabase["lib/supabase.js"] +end +App --> Store +Store --> CsvLib +Store --> Supabase +CsvLib --> |"Read/Write CSV"| App +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [csv.js](file://src/lib/csv.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Core Components +- CSV parsing and generation utilities: + - Parsing CSV text into structured records + - Generating CSV from structured records + - Handling headers, quoting, escaping, and delimiters +- Integration with application state: + - Importing parsed records into the store + - Exporting current store data to CSV +- Persistence: + - Optional upload/download flows via Supabase (if used by higher-level components) + +Key responsibilities: +- Robust parsing with strict header matching and type coercion +- Validation and normalization of fields +- Error reporting per row/column for malformed data +- Efficient streaming-friendly processing for large datasets + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) +- [store.jsx](file://src/store.jsx) + +## Architecture Overview +The CSV workflow involves three main phases: parse, validate, and persist/export. + +```mermaid +sequenceDiagram +participant UI as "UI Layer" +participant Store as "Store" +participant Csv as "CSV Library" +participant DB as "Supabase Client" +UI->>Csv : "Parse CSV text" +Csv-->>UI : "Records + Errors" +UI->>Store : "Import records" +Store->>DB : "Persist records (optional)" +DB-->>Store : "Result" +Store-->>UI : "Updated state" +UI->>Store : "Export data" +Store->>Csv : "Generate CSV" +Csv-->>UI : "CSV text" +UI->>UI : "Download file" +``` + +**Diagram sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### CSV Format Specifications +- Delimiter: comma +- Quoting: double quotes around fields containing delimiter, quote, or newline +- Escaping: double-quote inside quoted fields is escaped by doubling it +- Header row: required; must match expected column names exactly +- Encoding: UTF-8 recommended +- Line endings: CRLF or LF accepted +- Empty rows: ignored during parsing +- Trailing commas: treated as empty trailing field if present + +Supported data types and formats: +- Text: any string value +- Numbers: integers and decimals using locale-independent decimal separator (dot) +- Dates: ISO 8601 strings (YYYY-MM-DD) +- Booleans: true/false (case-insensitive) +- Nulls: empty values are normalized to null unless otherwise specified + +Field mapping: +- Column names in the CSV header map directly to internal field names +- Extra columns are ignored unless explicitly mapped +- Missing columns result in null values for those fields + +Examples of valid CSV structures: +- Minimal dataset with required headers and one record +- Dataset with optional fields and mixed data types +- Dataset with quoted fields containing commas and embedded quotes + +Common import scenarios: +- Overwrite existing dataset +- Append to existing dataset +- Merge by unique key (e.g., ID) when provided + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) + +### Field Mappings and Data Validation Rules +- Required fields: defined by schema; missing required fields cause row-level errors +- Type coercion: + - Numeric fields accept digits, optional sign, and a single dot for decimals + - Date fields accept ISO 8601 date strings only + - Boolean fields accept true/false variants +- Range and length constraints: + - Numeric ranges enforced where applicable + - String lengths validated against schema limits +- Uniqueness constraints: + - Unique keys enforced across imported records +- Cross-field validations: + - Conditional dependencies between fields validated post-coercion + +Error reporting: +- Per-row error list with column names and messages +- Summary counts of successful vs failed rows +- Option to skip invalid rows and continue processing + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) + +### Bulk Import Operations +- Batch size: configurable chunk size to balance memory usage and throughput +- Progress tracking: + - Events emitted for total rows, processed rows, and errors + - Percentage complete and ETA based on processing rate +- Concurrency: + - Sequential processing by default to maintain order and simplify error handling + - Optional parallelism for independent tasks (e.g., network calls) with backpressure controls +- Transactional behavior: + - All-or-nothing import option to ensure consistency + - Partial commit mode to allow recovery after failures + +Progress tracking example flow: +```mermaid +flowchart TD +Start(["Start Import"]) --> Read["Read CSV in chunks"] +Read --> Parse["Parse chunk"] +Parse --> Validate["Validate rows"] +Validate --> Valid{"All valid?"} +Valid --> |Yes| Persist["Persist batch"] +Valid --> |No| Report["Report row errors"] +Persist --> NextChunk{"More chunks?"} +Report --> NextChunk +NextChunk --> |Yes| Read +NextChunk --> |No| Finish(["Finish Import"]) +``` + +**Diagram sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) + +### Error Handling for Malformed Data +- Parser errors: + - Invalid quoting or escaping detected + - Inconsistent number of columns per row +- Validation errors: + - Missing required fields + - Type mismatches + - Constraint violations +- Recovery strategies: + - Skip invalid rows and continue + - Collect all errors and present summary to user + - Provide downloadable error report with row numbers and messages + +User feedback: +- Inline warnings next to problematic fields +- Modal or toast notifications summarizing issues +- Option to download a detailed error log + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) + +### Export Capabilities +- Data filtering: + - Filter by date range, status, tags, or custom predicates + - Exclude sensitive fields based on permissions +- Formatting options: + - Select columns to include + - Choose output encoding (UTF-8 default) + - Control quoting behavior and delimiter selection +- File generation: + - Generate CSV text in-memory + - Trigger browser download with appropriate MIME type + - Support large exports via chunked generation and streaming download + +Security considerations: +- Sanitize exported content to prevent injection +- Respect user roles and data access policies + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) + +### Supported Data Types, Date Formats, and Encoding Standards +- Data types: + - Text, Number, Date, Boolean, Null +- Date formats: + - Input: ISO 8601 (YYYY-MM-DD) + - Output: ISO 8601 (YYYY-MM-DD) +- Encoding: + - UTF-8 recommended + - BOM handling: strip leading BOM if present +- Locale considerations: + - Decimal separator is dot regardless of locale + - Thousands separators are not supported in numeric fields + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) + +### Security Considerations for File Uploads and Data Sanitization +- Input validation: + - Strict schema enforcement before processing + - Reject unexpected or dangerous characters in text fields +- Size limits: + - Enforce maximum file size to prevent resource exhaustion +- Content-type checks: + - Ensure uploaded files are CSV +- Sanitization: + - Escape special characters and normalize whitespace + - Remove control characters except newlines and tabs where allowed +- Access control: + - Verify user permissions before importing or exporting data +- Audit logging: + - Log import/export actions for accountability + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis +The CSV module depends on application state and optionally on the persistence layer. + +```mermaid +graph LR +Csv["csv.js"] --> Store["store.jsx"] +Store --> Supabase["supabase.js"] +App["App.jsx"] --> Store +App --> Csv +``` + +**Diagram sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [store.jsx](file://src/store.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Chunked reading: process CSV in fixed-size chunks to reduce memory pressure +- Lazy evaluation: avoid unnecessary transformations until needed +- Indexing: precompute indexes for frequently filtered fields +- Backpressure: throttle persistence operations to avoid overwhelming the database +- Caching: cache parsed schemas and validation rules to minimize overhead + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Incorrect header names: + - Ensure exact match with expected schema + - Use mapping configuration if renaming is necessary +- Malformed rows: + - Check for inconsistent column counts + - Fix quoting and escaping issues +- Type conversion failures: + - Validate numeric formats and date strings + - Normalize boolean representations +- Large file performance: + - Reduce chunk size or enable streaming + - Monitor memory usage and adjust batch sizes +- Permission errors: + - Verify user roles and data access policies + +Diagnostic steps: +- Download error reports and review row numbers +- Inspect logs for parser and validator messages +- Test with minimal datasets to isolate issues + +**Section sources** +- [csv.js](file://src/lib/csv.js) +- [csv.test.js](file://src/lib/csv.test.js) + +## Conclusion +The CSV import/export system in ApplyGuard PH provides robust parsing, validation, and generation capabilities with comprehensive error handling and progress tracking. By adhering to the documented format specifications and security practices, users can reliably manage bulk data operations while maintaining data integrity and performance. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Example CSV Structures +- Minimal dataset: + - Headers: id,name,email + - One record with valid types +- Mixed types dataset: + - Headers: id,title,amount,date,active + - Records with numbers, dates, and booleans +- Quoted fields dataset: + - Headers: id,description + - Description includes commas and embedded quotes + +[No sources needed since this section provides conceptual examples] + +### Common Import Scenarios +- Overwrite dataset: + - Clear existing records and replace with imported data +- Append dataset: + - Add new records without modifying existing ones +- Merge by unique key: + - Update existing records by ID and insert new ones + +[No sources needed since this section provides conceptual examples] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Data Management/Local Storage & Persistence.md b/.qoder/repowiki/en/content/Data Management/Local Storage & Persistence.md new file mode 100644 index 0000000..3894eae --- /dev/null +++ b/.qoder/repowiki/en/content/Data Management/Local Storage & Persistence.md @@ -0,0 +1,490 @@ +# Local Storage & Persistence + + +**Referenced Files in This Document** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [sw.js](file://public/sw.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Data Models](#data-models) +7. [Storage Operations](#storage-operations) +8. [Offline Support](#offline-support) +9. [Performance Considerations](#performance-considerations) +10. [Error Handling](#error-handling) +11. [Migration Strategy](#migration-strategy) +12. [Backup & Restore](#backup--restore) +13. [Troubleshooting Guide](#troubleshooting-guide) +14. [Conclusion](#conclusion) + +## Introduction + +This document provides comprehensive documentation for the local storage implementation in ApplyGuard PH. The application employs a multi-layered persistence strategy that combines browser localStorage, IndexedDB for large datasets, and service workers for offline support. The architecture ensures data durability, performance optimization, and seamless user experience across different network conditions. + +The storage system is designed to handle job applications, offers tracking, user preferences, and application state while maintaining data consistency between local and cloud storage through synchronization mechanisms. + +## Project Structure + +The storage implementation follows a modular architecture with clear separation of concerns: + +```mermaid +graph TB +subgraph "Application Layer" +UI[React Components] +Store[Global State Store] +end +subgraph "Storage Layer" +StorageLib[Storage Library] +SyncEngine[Sync Engine] +CacheManager[Cache Manager] +end +subgraph "Persistence Layer" +LocalStorage[localStorage] +IndexedDB[IndexedDB] +ServiceWorker[Service Worker] +end +subgraph "Cloud Layer" +Supabase[Supabase Client] +CloudAPI[Cloud API] +end +UI --> Store +Store --> StorageLib +StorageLib --> LocalStorage +StorageLib --> IndexedDB +StorageLib --> ServiceWorker +StorageLib --> SyncEngine +SyncEngine --> Supabase +Supabase --> CloudAPI +``` + +**Diagram sources** +- [storage.js:1-50](file://src/lib/storage.js#L1-L50) +- [store.jsx:1-100](file://src/store.jsx#L1-L100) +- [sync.js:1-80](file://src/lib/sync.js#L1-L80) + +**Section sources** +- [storage.js:1-200](file://src/lib/storage.js#L1-L200) +- [store.jsx:1-150](file://src/store.jsx#L1-L150) + +## Core Components + +### Storage Library +The primary storage abstraction layer that provides a unified interface for all persistence operations. It handles serialization, deserialization, error handling, and fallback mechanisms. + +### Global State Store +Manages application state and coordinates between local storage and cloud synchronization. Implements reactive updates and state persistence. + +### Sync Engine +Handles bidirectional synchronization between local and cloud storage, managing conflict resolution and data consistency. + +### Service Worker +Provides offline capabilities, caching strategies, and background synchronization for improved user experience. + +**Section sources** +- [storage.js:50-150](file://src/lib/storage.js#L50-L150) +- [store.jsx:50-120](file://src/store.jsx#L50-L120) +- [sync.js:50-120](file://src/lib/sync.js#L50-L120) + +## Architecture Overview + +The storage architecture implements a layered approach with multiple fallback mechanisms: + +```mermaid +sequenceDiagram +participant App as Application +participant Store as State Store +participant Storage as Storage Library +participant Local as localStorage/IndexedDB +participant SW as Service Worker +participant Cloud as Cloud Storage +App->>Store : Update State +Store->>Storage : Persist Data +Storage->>Local : Write to Local Storage +Storage->>SW : Cache for Offline +Storage->>Cloud : Queue for Sync +Note over Storage,Cloud : Background Sync +App->>Store : Read State +Store->>Storage : Get Data +Storage->>Local : Read from Local +alt Network Available +Storage->>Cloud : Fetch Latest +Cloud-->>Storage : Remote Data +Storage->>Store : Merge & Return +else Offline +Storage-->>Store : Local Data +end +``` + +**Diagram sources** +- [store.jsx:100-200](file://src/store.jsx#L100-L200) +- [storage.js:100-250](file://src/lib/storage.js#L100-L250) +- [sync.js:100-200](file://src/lib/sync.js#L100-L200) + +## Detailed Component Analysis + +### Storage Library Implementation + +The storage library provides a comprehensive abstraction over browser storage APIs with advanced features: + +#### Key Features +- **Automatic Serialization**: JSON-based data serialization with custom type support +- **Error Handling**: Graceful fallbacks when storage is unavailable +- **Version Management**: Schema versioning for data migrations +- **Performance Optimization**: Batch operations and lazy loading +- **Type Safety**: TypeScript interfaces for data models + +#### Storage Strategies +- **Small Data**: Uses localStorage for configuration and preferences +- **Large Datasets**: Leverages IndexedDB for job applications and offers +- **Caching**: Service worker cache for frequently accessed data +- **Background Sync**: Automatic synchronization when network is available + +**Section sources** +- [storage.js:1-300](file://src/lib/storage.js#L1-L300) + +### Global State Store + +The global store manages application state with automatic persistence: + +#### State Management Pattern +- **Centralized State**: Single source of truth for application data +- **Reactive Updates**: Components automatically re-render on state changes +- **Persistence Integration**: Seamless save/load from storage +- **Undo/Redo**: Operation history for critical actions + +#### State Categories +- **User Preferences**: Theme settings, notification preferences +- **Job Applications**: Application data, interview schedules +- **Offers Tracking**: Salary negotiations, offer comparisons +- **Analytics**: Usage statistics and performance metrics + +**Section sources** +- [store.jsx:1-250](file://src/store.jsx#L1-L250) + +### Synchronization Engine + +The sync engine handles complex synchronization scenarios: + +#### Conflict Resolution +- **Last Write Wins**: Simple timestamp-based resolution +- **Field-Level Merging**: Intelligent merging of non-conflicting fields +- **Manual Resolution**: User intervention for complex conflicts + +#### Sync Triggers +- **Network Availability**: Automatic sync when connection restored +- **Manual Sync**: User-initiated synchronization +- **Periodic Sync**: Background synchronization at intervals + +**Section sources** +- [sync.js:1-200](file://src/lib/sync.js#L1-L200) + +## Data Models + +### Job Application Model + +```mermaid +erDiagram +JOB_APPLICATION { +uuid id PK +string company_name +string position_title +string status +datetime applied_date +datetime last_updated +float salary_range_min +float salary_range_max +string location +string remote_option +text notes +json skills_required +boolean follow_up_scheduled +datetime next_follow_up +} +OFFER { +uuid id PK +uuid application_id FK +string company_name +float base_salary +float bonus_amount +float equity_value +string benefits_summary +datetime offer_date +datetime deadline +string status +json negotiation_notes +} +USER_PREFERENCES { +uuid id PK +string theme +boolean notifications_enabled +string language +json dashboard_layout +datetime last_sync +} +JOB_APPLICATION ||--o{ OFFER : has +``` + +**Diagram sources** +- [storage.js:200-400](file://src/lib/storage.js#L200-L400) + +### Data Validation Rules + +Each data model includes validation rules to ensure data integrity: + +- **Required Fields**: Company name, position title, application date +- **Format Validation**: Email addresses, phone numbers, URLs +- **Range Validation**: Salary ranges, dates within reasonable bounds +- **Business Logic**: Status transitions, dependency checks + +**Section sources** +- [storage.js:300-500](file://src/lib/storage.js#L300-L500) + +## Storage Operations + +### Basic CRUD Operations + +#### Create Operations +- **Batch Creation**: Multiple records created atomically +- **Validation**: Pre-save validation with detailed error messages +- **Default Values**: Automatic population of missing required fields + +#### Read Operations +- **Query Interface**: Flexible querying with filters and sorting +- **Pagination**: Efficient handling of large datasets +- **Caching**: In-memory caching for frequently accessed data + +#### Update Operations +- **Partial Updates**: Update specific fields without overwriting entire records +- **Optimistic Updates**: Immediate UI feedback with rollback on failure +- **Audit Trail**: Change history for critical data modifications + +#### Delete Operations +- **Soft Deletes**: Mark records as deleted rather than permanent removal +- **Cascade Deletion**: Automatic cleanup of related records +- **Recovery**: Undo delete operations within time window + +**Section sources** +- [storage.js:400-700](file://src/lib/storage.js#L400-L700) + +### Advanced Operations + +#### Search and Filtering +- **Full-text Search**: Text search across multiple fields +- **Advanced Filters**: Complex query building with logical operators +- **Saved Searches**: Frequently used filter combinations + +#### Export and Import +- **JSON Export**: Complete data export for backup purposes +- **CSV Export**: Spreadsheet-compatible format for analysis +- **Selective Export**: Export specific data categories + +**Section sources** +- [storage.js:600-900](file://src/lib/storage.js#L600-L900) + +## Offline Support + +### Service Worker Implementation + +The service worker provides comprehensive offline capabilities: + +#### Caching Strategies +- **Static Assets**: Aggressive caching for CSS, JavaScript, images +- **API Responses**: Stale-while-revalidate pattern for API calls +- **User Data**: Optimistic caching with background sync + +#### Offline Detection +- **Network Monitoring**: Real-time network status detection +- **Connection Quality**: Adaptive behavior based on connection speed +- **Predictive Loading**: Pre-fetch likely needed resources + +#### Background Processing +- **Queue Management**: Pending operations queued during offline periods +- **Conflict Resolution**: Smart merging when reconnecting +- **Progress Reporting**: User feedback on sync progress + +**Section sources** +- [sw.js:1-200](file://public/sw.js#L1-L200) +- [sync.js:150-300](file://src/lib/sync.js#L150-L300) + +### Offline Data Access + +Users can continue working seamlessly when offline: + +- **Read Operations**: Full access to cached data +- **Write Operations**: Changes queued and applied when online +- **UI Feedback**: Clear indicators of offline mode and pending changes +- **Data Consistency**: Automatic reconciliation when back online + +**Section sources** +- [sw.js:100-250](file://public/sw.js#L100-L250) + +## Performance Considerations + +### Storage Optimization + +#### Memory Management +- **Lazy Loading**: Load data on demand rather than upfront +- **Memory Limits**: Automatic eviction of least recently used items +- **Garbage Collection**: Regular cleanup of unused data + +#### Database Indexing +- **Strategic Indexes**: Optimized indexes for common queries +- **Composite Indexes**: Multi-field indexes for complex searches +- **Index Maintenance**: Periodic index optimization + +#### Query Optimization +- **Query Planning**: Efficient query execution plans +- **Result Caching**: Cache frequent query results +- **Batch Operations**: Group database operations for efficiency + +### Large Dataset Handling + +For applications with thousands of job applications and offers: + +- **Pagination**: Load data in chunks rather than all at once +- **Virtual Scrolling**: Render only visible items in lists +- **Database Partitioning**: Split large tables by date or category +- **Compression**: Compress large text fields and attachments + +**Section sources** +- [storage.js:700-1000](file://src/lib/storage.js#L700-L1000) + +## Error Handling + +### Storage Errors + +Comprehensive error handling for various failure scenarios: + +#### Common Error Types +- **QuotaExceededError**: Storage space limits reached +- **SecurityError**: Cross-origin restrictions +- **InvalidStateError**: Invalid storage state +- **NetworkError**: Connection failures during sync + +#### Recovery Strategies +- **Automatic Retry**: Exponential backoff for transient failures +- **Fallback Storage**: Switch to alternative storage methods +- **Data Recovery**: Attempt to recover corrupted data +- **User Notification**: Clear error messages with recovery options + +#### Logging and Diagnostics +- **Error Tracking**: Comprehensive error logging +- **Performance Metrics**: Storage operation timing and success rates +- **Usage Analytics**: Storage usage patterns and trends + +**Section sources** +- [storage.js:800-1200](file://src/lib/storage.js#L800-L1200) + +## Migration Strategy + +### Version Management + +The storage system supports seamless data migrations: + +#### Schema Versioning +- **Version Tracking**: Current schema version stored with data +- **Migration Scripts**: Automated migration procedures +- **Rollback Support**: Ability to revert failed migrations + +#### Migration Process +1. **Version Check**: Compare current schema with latest +2. **Migration Execution**: Run necessary migration scripts +3. **Validation**: Verify data integrity post-migration +4. **Cleanup**: Remove deprecated data structures + +#### Backward Compatibility +- **Graceful Degradation**: Support older data formats +- **Auto-upgrade**: Transparent data format upgrades +- **Legacy Support**: Maintain compatibility with previous versions + +**Section sources** +- [storage.js:900-1100](file://src/lib/storage.js#L900-L1100) + +## Backup & Restore + +### Backup Mechanisms + +Multiple backup strategies ensure data safety: + +#### Automatic Backups +- **Scheduled Backups**: Regular automated backups +- **Change Detection**: Incremental backups based on changes +- **Cloud Sync**: Automatic upload to cloud storage + +#### Manual Backups +- **Export Functionality**: User-initiated data exports +- **Selective Backup**: Choose specific data categories +- **Compression**: Compressed backup files for efficient storage + +### Restore Process + +Robust restore functionality for disaster recovery: + +#### Restore Options +- **Full Restore**: Complete data restoration from backup +- **Selective Restore**: Restore specific data categories +- **Merge Restore**: Combine backup data with existing data + +#### Data Integrity +- **Validation**: Verify backup integrity before restore +- **Conflict Resolution**: Handle conflicts between existing and backup data +- **Rollback**: Automatic rollback if restore fails + +**Section sources** +- [storage.js:1000-1300](file://src/lib/storage.js#L1000-L1300) + +## Troubleshooting Guide + +### Common Issues + +#### Storage Capacity Problems +- **Symptoms**: Failed saves, data loss warnings +- **Diagnosis**: Check storage quota usage +- **Solutions**: Clean up old data, implement data retention policies + +#### Sync Conflicts +- **Symptoms**: Duplicate records, inconsistent data +- **Diagnosis**: Review sync logs and conflict resolution history +- **Solutions**: Manual conflict resolution, adjust sync policies + +#### Performance Issues +- **Symptoms**: Slow app response, high memory usage +- **Diagnosis**: Monitor storage operation performance +- **Solutions**: Optimize queries, implement caching, reduce data size + +### Debug Tools + +#### Storage Inspector +- **Data Browser**: Visual inspection of stored data +- **Operation Logs**: Detailed logs of storage operations +- **Performance Metrics**: Real-time performance monitoring + +#### Diagnostic Reports +- **Storage Health**: Overall storage system health report +- **Error Summary**: Recent errors and their frequency +- **Usage Statistics**: Storage usage patterns and trends + +**Section sources** +- [storage.js:1100-1400](file://src/lib/storage.js#L1100-L1400) + +## Conclusion + +The local storage implementation in ApplyGuard PH provides a robust, scalable, and user-friendly persistence solution. The multi-layered architecture ensures data durability, performance optimization, and seamless offline support. Key strengths include: + +- **Comprehensive Abstraction**: Unified interface for all storage operations +- **Intelligent Caching**: Optimized data access patterns +- **Robust Error Handling**: Graceful degradation and recovery +- **Offline First**: Seamless offline experience with background sync +- **Scalable Design**: Handles growing datasets efficiently +- **Data Integrity**: Validation, migration, and backup mechanisms + +The implementation follows modern web standards and best practices, ensuring long-term maintainability and compatibility with evolving browser capabilities. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Deployment & DevOps.md b/.qoder/repowiki/en/content/Deployment & DevOps.md new file mode 100644 index 0000000..cc81de4 --- /dev/null +++ b/.qoder/repowiki/en/content/Deployment & DevOps.md @@ -0,0 +1,390 @@ +# Deployment & DevOps + + +**Referenced Files in This Document** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive deployment and DevOps guidance for ApplyGuard PH across Netlify and Vercel, including CI/CD configuration, environment variable management, secrets handling, monitoring, logging, error tracking, rollback procedures, backup strategies, disaster recovery, performance monitoring, alerting thresholds, and maintenance procedures. It is intended for engineers, SREs, and operators who need to deploy, operate, and maintain the application reliably. + +## Project Structure +The project is a client-side web application with Supabase Edge Functions and migrations. The build toolchain uses Vite, and mobile packaging is configured via Capacitor. Key deployment-related files include: +- Build and runtime configuration: netlify.toml, vercel.json, vite.config.js, package.json +- CI/CD: .github/workflows/supabase.yml +- Backend configuration: supabase/config.toml +- Client-side Supabase integration: src/lib/supabase.js +- Service worker: public/sw.js +- Mobile packaging: capacitor.config.ts + +```mermaid +graph TB +subgraph "Build & Deploy" +A["Vite Build
vite.config.js"] +B["Netlify Config
netlify.toml"] +C["Vercel Config
vercel.json"] +D["Package Scripts
package.json"] +end +subgraph "Runtime" +E["Frontend SPA"] +F["Supabase Client
src/lib/supabase.js"] +G["Edge Functions"] +H["Service Worker
public/sw.js"] +end +subgraph "CI/CD" +I["GitHub Actions
.github/workflows/supabase.yml"] +J["Supabase CLI Config
supabase/config.toml"] +end +A --> E +B --> E +C --> E +D --> A +E --> F +E --> G +E --> H +I --> J +``` + +**Diagram sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Core Components +- Build system: Vite-based frontend build with configurable base path and output directory. +- Hosting targets: Netlify and Vercel, each with their own configuration file. +- CI/CD: GitHub Actions workflow focused on Supabase operations (migrations/functions). +- Runtime integrations: Supabase client initialization and service worker registration. +- Mobile packaging: Capacitor configuration for building native apps from the same codebase. + +Key responsibilities: +- netlify.toml: Defines build command, publish directory, redirects, headers, and environment variables for Netlify. +- vercel.json: Defines build command, output directory, rewrites, headers, and environment variables for Vercel. +- vite.config.js: Controls build behavior such as base path and asset handling. +- package.json: Contains scripts for build, test, lint, and other tasks used by CI/CD and local development. +- .github/workflows/supabase.yml: Automates Supabase migrations and function deployments. +- supabase/config.toml: Declares functions and migrations paths for Supabase CLI. +- src/lib/supabase.js: Initializes Supabase client using environment variables. +- public/sw.js: Registers and manages the service worker for caching and offline behaviors. +- capacitor.config.ts: Configures Capacitor for mobile builds. + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Architecture Overview +The application follows a static-site architecture with serverless backend capabilities via Supabase Edge Functions. Frontend assets are built by Vite and deployed to Netlify or Vercel. Supabase client calls are made at runtime from the browser. CI/CD automates database migrations and function deployments through GitHub Actions and the Supabase CLI. + +```mermaid +graph TB +U["User Browser"] +CDN["CDN / Edge Cache"] +FE["Static Frontend
Built by Vite"] +SW["Service Worker
public/sw.js"] +API["Supabase Client
src/lib/supabase.js"] +EF["Supabase Edge Functions"] +DB["Supabase Database"] +CI["GitHub Actions
.github/workflows/supabase.yml"] +SCFG["Supabase CLI Config
supabase/config.toml"] +U --> CDN --> FE +FE --> SW +FE --> API +API --> EF +API --> DB +CI --> SCFG +CI --> EF +CI --> DB +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [public/sw.js](file://public/sw.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) + +## Detailed Component Analysis + +### Multi-Platform Deployment Strategies + +#### Netlify Deployment +- Build command and publish directory are defined in the Netlify configuration file. +- Environment variables can be set per branch or globally within the Netlify UI or via CI. +- Redirects and headers should be configured to support SPA routing and security policies. +- Ensure that any required Supabase client variables are provided in Netlify’s environment settings. + +Operational notes: +- Use branch-specific environments for preview deployments. +- Pin dependency versions in the lockfile to ensure reproducible builds. +- Validate that the base path aligns with your hosting URL structure. + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [package.json](file://package.json) + +#### Vercel Deployment +- Build command and output directory are specified in the Vercel configuration file. +- Environment variables can be managed per environment (development, preview, production). +- Rewrites and headers should be configured to support SPA routing and security requirements. +- Align base path and asset URLs with Vercel’s deployment domains. + +Operational notes: +- Use Vercel’s Preview Deployments for pull request previews. +- Keep environment variables consistent between platforms to avoid drift. +- Confirm that edge functions (if used) are compatible with Vercel’s runtime if you migrate them. + +**Section sources** +- [vercel.json](file://vercel.json) +- [package.json](file://package.json) + +#### Shared Build Configuration (Vite) +- Configure base path and output directory to match platform expectations. +- Ensure asset handling and caching headers are appropriate for long-term caching. +- Avoid hardcoding environment-specific values; use build-time env variables where necessary. + +**Section sources** +- [vite.config.js](file://vite.config.js) + +### CI/CD Pipeline Configuration + +#### GitHub Actions Workflow for Supabase +- The workflow automates Supabase operations such as migrations and function deployments. +- It uses the Supabase CLI and requires authentication tokens configured as repository secrets. +- The workflow references the Supabase CLI configuration to locate functions and migrations. + +Recommended practices: +- Separate workflows for migrations and function deployments if needed. +- Add matrix testing for multiple Node versions if applicable. +- Include artifact uploads for build outputs when debugging failures. + +**Section sources** +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) + +### Automated Testing Workflows +- Unit tests are present for several libraries under src/lib/*.test.js. +- Integrate test execution into CI to fail builds on test regressions. +- Consider adding coverage reporting and threshold enforcement. + +Suggested steps: +- Add a CI job that installs dependencies and runs the test script defined in package.json. +- Cache node_modules to speed up CI runs. +- Publish test results as artifacts for review. + +**Section sources** +- [package.json](file://package.json) + +### Environment Variable Management and Secrets Handling + +#### Client-Side Variables +- The Supabase client initializes using environment variables. Ensure these are injected at build time or runtime depending on platform capabilities. +- For Netlify/Vercel, define variables in the platform’s environment settings. +- Avoid committing secrets to version control; use platform secret managers. + +Best practices: +- Prefix client variables clearly (e.g., VITE_SUPABASE_URL) if using Vite’s build-time injection. +- Validate presence of required variables during startup and surface clear errors. +- Rotate secrets regularly and audit access. + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +#### Server-Side and Edge Function Secrets +- Store secrets for Edge Functions in Supabase project settings or platform secret managers. +- Access secrets securely within functions without exposing them to the client. +- Use separate keys per environment (dev, staging, prod). + +**Section sources** +- [supabase/config.toml](file://supabase/config.toml) + +### Monitoring Setup, Logging, and Error Tracking + +#### Logging Strategy +- Centralize logs from Edge Functions and Supabase operations. +- Capture structured logs with correlation IDs for request tracing. +- Implement log sampling for high-volume endpoints. + +#### Error Tracking +- Integrate an error tracking service (e.g., Sentry) in the frontend to capture unhandled exceptions and user context. +- Track network errors and failed API calls with meaningful messages. +- Set up alerts for critical error spikes. + +#### Observability +- Enable metrics for frontend performance (LCP, FID, CLS) and backend latency. +- Use distributed tracing across client, Edge Functions, and database queries. + +[No sources needed since this section provides general guidance] + +### Rollback Procedures, Backup Strategies, and Disaster Recovery + +#### Rollback Procedures +- Maintain previous stable releases on Netlify/Vercel for quick rollbacks. +- Use Git tags and environment-specific branches to pin deployments. +- For Supabase, keep migration history and consider snapshotting schema state before major changes. + +#### Backup Strategies +- Schedule regular backups of Supabase databases and storage buckets. +- Export critical data periodically and store backups off-platform. +- Test restore procedures regularly. + +#### Disaster Recovery +- Define RTO/RPO targets and document recovery steps. +- Maintain runbooks for common failure scenarios (database corruption, misconfiguration, supply chain issues). +- Conduct periodic drills to validate recovery processes. + +[No sources needed since this section provides general guidance] + +### Performance Monitoring, Alerting Thresholds, and Maintenance Procedures + +#### Performance Monitoring +- Monitor core web vitals and backend response times. +- Track cache hit ratios and service worker effectiveness. +- Profile large assets and optimize bundle size. + +#### Alerting Thresholds +- Set alerts for error rates exceeding acceptable levels. +- Alert on latency p95/p99 spikes and resource exhaustion. +- Notify on failed CI/CD jobs and deployment rollbacks. + +#### Maintenance Procedures +- Regularly update dependencies and apply security patches. +- Review and prune unused features and configurations. +- Periodically audit environment variables and permissions. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis + +```mermaid +graph LR +P["package.json"] +V["vite.config.js"] +N["netlify.toml"] +Vc["vercel.json"] +GH[".github/workflows/supabase.yml"] +SC["supabase/config.toml"] +SB["src/lib/supabase.js"] +SW["public/sw.js"] +CAP["capacitor.config.ts"] +P --> V +V --> N +V --> Vc +GH --> SC +SB --> SW +CAP --> V +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Performance Considerations +- Optimize bundle size and enable code splitting to reduce initial load time. +- Leverage caching headers and service worker strategies for static assets. +- Minimize third-party dependencies and prefer lightweight alternatives. +- Use CDN and edge caching to serve assets closer to users. +- Profile and monitor performance continuously to catch regressions early. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Build failures due to missing environment variables: Verify platform environment settings and CI secrets. +- Routing issues on SPA deployments: Ensure redirects/rewrites are configured correctly in netlify.toml and vercel.json. +- Supabase client initialization errors: Check that client variables are correctly injected and accessible at runtime. +- Service worker not updating: Clear caches and verify cache-busting strategies. +- CI/CD pipeline failures: Inspect workflow logs and ensure Supabase CLI configuration paths are correct. + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [public/sw.js](file://public/sw.js) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [supabase/config.toml](file://supabase/config.toml) + +## Conclusion +ApplyGuard PH is designed for straightforward multi-platform deployment with robust CI/CD automation for Supabase operations. By following the environment management, monitoring, and operational procedures outlined here, teams can achieve reliable deployments, rapid rollbacks, and strong observability across Netlify and Vercel. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Appendix A: Environment Variables Checklist +- Supabase client URL and anonymous/public key +- Feature flags and analytics identifiers +- Third-party service credentials (stored securely) +- Build-time vs runtime variables distinction + +[No sources needed since this section provides general guidance] + +### Appendix B: CI/CD Job Templates +- Lint and test job +- Build job with artifact upload +- Deploy job with environment promotion +- Supabase migration and function deployment job + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Developer Guidelines.md b/.qoder/repowiki/en/content/Developer Guidelines.md new file mode 100644 index 0000000..8baf35f --- /dev/null +++ b/.qoder/repowiki/en/content/Developer Guidelines.md @@ -0,0 +1,568 @@ +# Developer Guidelines + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/mobile.js](file://src/mobile.js) +- [src/index.css](file://src/index.css) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/hooks/useCountUp.js](file://src/hooks/useCountUp.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/share.js](file://src/lib/share.js) +- [src/lib/csv.js](file://src/lib/csv.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/prompt.js](file://src/lib/prompt.js) +- [src/lib/tone.js](file://src/lib/tone.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/config.toml](file://supabase/config.toml) +- [.github/workflows/supabase.yml](file:.github/workflows/supabase.yml) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion +10. Appendices + +## Introduction +This document provides comprehensive developer guidelines for contributing to and developing ApplyGuard PH. It covers code standards, tooling configuration, Git workflow, pull request and review practices, issue reporting, debugging and profiling techniques, performance optimization strategies, common troubleshooting scenarios, known limitations, extension points, environment setup, dependency management, and release procedures. The goal is to help contributors work efficiently and consistently across the frontend web app, Supabase backend functions, and mobile packaging. + +## Project Structure +ApplyGuard PH is a Vite-based React application with Supabase Edge Functions for server-side logic, migrations for database schema, and Capacitor for optional mobile packaging. Key directories: +- src: Frontend source (React components, hooks, libraries) +- supabase: Edge Functions, migrations, and Supabase config +- public: Static assets including PWA manifest and service worker +- scripts: Utility scripts +- docs: Planning and handoff documents +- .github/workflows: CI workflows for Supabase deployment + +```mermaid +graph TB +A["Frontend App
src/main.jsx"] --> B["App Shell
src/App.jsx"] +B --> C["Layout & Pages
src/components/*"] +B --> D["State Store
src/store.jsx"] +B --> E["Auth Module
src/auth.jsx"] +B --> F["Libraries
src/lib/*"] +F --> G["Supabase Client
src/lib/supabase.js"] +F --> H["Local Storage
src/lib/storage.js"] +F --> I["Entitlements & Billing
src/lib/entitlement.js, billing.js"] +F --> J["AI Integration
src/lib/ai.js"] +B --> K["Mobile Entry
src/mobile.js"] +L["PWA Assets
public/*"] --> A +M["Supabase Functions
supabase/functions/*"] --> N["Shared Utils
supabase/functions/_shared/*"] +O["Migrations
supabase/migrations/*"] --> P["Supabase DB"] +Q["CI Workflow
.github/workflows/supabase.yml"] --> M +``` + +**Diagram sources** +- [src/main.jsx:1-50](file://src/main.jsx#L1-L50) +- [src/App.jsx:1-120](file://src/App.jsx#L1-L120) +- [src/store.jsx:1-120](file://src/store.jsx#L1-L120) +- [src/auth.jsx:1-120](file://src/auth.jsx#L1-L120) +- [src/mobile.js:1-60](file://src/mobile.js#L1-L60) +- [src/lib/supabase.js:1-120](file://src/lib/supabase.js#L1-L120) +- [src/lib/storage.js:1-120](file://src/lib/storage.js#L1-L120) +- [src/lib/entitlement.js:1-120](file://src/lib/entitlement.js#L1-L120) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/ai.js:1-120](file://src/lib/ai.js#L1-L120) +- [public/sw.js:1-120](file://public/sw.js#L1-L120) +- [public/manifest.webmanifest:1-60](file://public/manifest.webmanifest#L1-L60) +- [supabase/functions/_shared/http.ts:1-120](file://supabase/functions/_shared/http.ts#L1-L120) +- [supabase/functions/_shared/paypal.ts:1-120](file://supabase/functions/_shared/paypal.ts#L1-L120) +- [supabase/functions/_shared/entitlement.ts:1-120](file://supabase/functions/_shared/entitlement.ts#L1-L120) +- [supabase/functions/create-checkout/index.ts:1-120](file://supabase/functions/create-checkout/index.ts#L1-L120) +- [supabase/functions/capture-paypal-order/index.ts:1-120](file://supabase/functions/capture-paypal-order/index.ts#L1-L120) +- [supabase/functions/create-paypal-order/index.ts:1-120](file://supabase/functions/create-paypal-order/index.ts#L1-L120) +- [supabase/functions/paymongo-webhook/index.ts:1-120](file://supabase/functions/paymongo-webhook/index.ts#L1-L120) +- [supabase/functions/paypal-webhook/index.ts:1-120](file://supabase/functions/paypal-webhook/index.ts#L1-L120) +- [supabase/functions/ai-proxy/index.ts:1-120](file://supabase/functions/ai-proxy/index.ts#L1-L120) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) +- [.github/workflows/supabase.yml:1-120](file:.github/workflows/supabase.yml#L1-L120) + +**Section sources** +- [README.md:1-120](file://README.md#L1-L120) +- [package.json:1-120](file://package.json#L1-L120) +- [vite.config.js:1-120](file://vite.config.js#L1-L120) +- [capacitor.config.ts:1-120](file://capacitor.config.ts#L1-L120) + +## Core Components +- Application entry and shell: + - Entry point initializes the React app and integrates PWA assets. + - App shell manages routing, layout, and global state initialization. +- State and persistence: + - Centralized store coordinates UI state and integrates with local storage and cloud sync. +- Authentication: + - Auth module handles user sessions and integrates with Supabase auth. +- Feature modules: + - AI assistant integration for prompt generation and responses. + - Scoring, red flags, stats, follow-ups, CSV export/import, sharing utilities. + - Entitlements and billing orchestrate subscription checks and checkout flows. +- Mobile packaging: + - Capacitor configuration and mobile entry bridge. + +Key responsibilities and interactions are implemented across src/components, src/lib, and supabase/functions. + +**Section sources** +- [src/main.jsx:1-80](file://src/main.jsx#L1-L80) +- [src/App.jsx:1-150](file://src/App.jsx#L1-L150) +- [src/store.jsx:1-150](file://src/store.jsx#L1-L150) +- [src/auth.jsx:1-150](file://src/auth.jsx#L1-L150) +- [src/lib/ai.js:1-120](file://src/lib/ai.js#L1-L120) +- [src/lib/scoring.js:1-120](file://src/lib/scoring.js#L1-L120) +- [src/lib/redflags.js:1-120](file://src/lib/redflags.js#L1-L120) +- [src/lib/stats.js:1-120](file://src/lib/stats.js#L1-L120) +- [src/lib/followups.js:1-120](file://src/lib/followups.js#L1-L120) +- [src/lib/csv.js:1-120](file://src/lib/csv.js#L1-L120) +- [src/lib/share.js:1-120](file://src/lib/share.js#L1-L120) +- [src/lib/entitlement.js:1-120](file://src/lib/entitlement.js#L1-L120) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [capacitor.config.ts:1-120](file://capacitor.config.ts#L1-L120) + +## Architecture Overview +The system comprises: +- Frontend React app built with Vite, using React Router and a centralized store. +- Supabase client for authentication and data operations. +- Supabase Edge Functions for secure server-side logic (billing, AI proxy). +- Database schema managed via migrations. +- Optional mobile packaging via Capacitor. +- PWA support through service worker and manifest. + +```mermaid +sequenceDiagram +participant User as "User" +participant FE as "Frontend App" +participant SB as "Supabase Client" +participant EF as "Edge Functions" +participant DB as "Supabase DB" +participant Pay as "Payment Provider" +User->>FE : "Open app / perform action" +FE->>SB : "Authenticate / query data" +SB-->>FE : "Auth state / records" +FE->>EF : "Create checkout / webhook handling" +EF->>Pay : "Initiate payment flow" +Pay-->>EF : "Webhook events" +EF->>DB : "Update entitlements / orders" +DB-->>EF : "Confirmation" +EF-->>FE : "Result / token" +FE-->>User : "UI updates / notifications" +``` + +**Diagram sources** +- [src/lib/supabase.js:1-120](file://src/lib/supabase.js#L1-L120) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-120](file://src/lib/entitlement.js#L1-L120) +- [supabase/functions/create-checkout/index.ts:1-120](file://supabase/functions/create-checkout/index.ts#L1-L120) +- [supabase/functions/paymongo-webhook/index.ts:1-120](file://supabase/functions/paymongo-webhook/index.ts#L1-L120) +- [supabase/functions/paypal-webhook/index.ts:1-120](file://supabase/functions/paypal-webhook/index.ts#L1-L120) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +## Detailed Component Analysis + +### Frontend App Shell and Routing +- Entry point bootstraps React and integrates PWA assets. +- App shell sets up routes, layout, and global state initialization. +- Layout component wraps pages and provides consistent navigation and header/footer. + +```mermaid +flowchart TD +Start(["App Start"]) --> InitStore["Initialize Store"] +InitStore --> LoadAuth["Load Auth State"] +LoadAuth --> RouteTo["Route Based on Auth"] +RouteTo --> |Authenticated| Dashboard["Dashboard / Tracker"] +RouteTo --> |Guest| Landing["Landing / Offers"] +Dashboard --> Actions["Perform Actions"] +Actions --> UpdateState["Update Store"] +UpdateState --> Persist["Persist to Local Storage"] +Persist --> End(["Render UI"]) +``` + +**Diagram sources** +- [src/main.jsx:1-80](file://src/main.jsx#L1-L80) +- [src/App.jsx:1-150](file://src/App.jsx#L1-L150) +- [src/store.jsx:1-150](file://src/store.jsx#L1-L150) +- [src/components/Layout.jsx:1-120](file://src/components/Layout.jsx#L1-L120) + +**Section sources** +- [src/main.jsx:1-80](file://src/main.jsx#L1-L80) +- [src/App.jsx:1-150](file://src/App.jsx#L1-L150) +- [src/components/Layout.jsx:1-120](file://src/components/Layout.jsx#L1-L120) + +### Authentication Flow +- Handles login, logout, and session persistence. +- Integrates with Supabase auth and updates store state. +- Protects routes based on authentication status. + +```mermaid +sequenceDiagram +participant User as "User" +participant FE as "Frontend App" +participant Auth as "Auth Module" +participant SB as "Supabase Client" +participant Store as "Store" +User->>FE : "Click Login" +FE->>Auth : "initAuth()" +Auth->>SB : "signInWithPassword() / signUp()" +SB-->>Auth : "Session" +Auth->>Store : "setUser(session)" +Store-->>FE : "Re-render protected routes" +User->>FE : "Logout" +FE->>Auth : "signOut()" +Auth->>SB : "signOut()" +SB-->>Auth : "Success" +Auth->>Store : "clearUser()" +``` + +**Diagram sources** +- [src/auth.jsx:1-150](file://src/auth.jsx#L1-L150) +- [src/lib/supabase.js:1-120](file://src/lib/supabase.js#L1-L120) +- [src/store.jsx:1-150](file://src/store.jsx#L1-L150) + +**Section sources** +- [src/auth.jsx:1-150](file://src/auth.jsx#L1-L150) +- [src/lib/supabase.js:1-120](file://src/lib/supabase.js#L1-L120) +- [src/store.jsx:1-150](file://src/store.jsx#L1-L150) + +### Billing and Entitlements +- Orchestrates checkout creation and webhook fulfillment. +- Checks entitlements before enabling premium features. +- Integrates with PayPal and PayMongo providers via Edge Functions. + +```mermaid +sequenceDiagram +participant FE as "Frontend App" +participant Billing as "Billing Lib" +participant EF as "Create Checkout Function" +participant Pay as "PayPal/PayMongo" +participant Webhook as "Webhook Handler" +participant DB as "Supabase DB" +FE->>Billing : "createCheckout(planId)" +Billing->>EF : "POST /create-checkout" +EF->>Pay : "Create order/session" +Pay-->>EF : "Return URL / session ID" +EF-->>FE : "Redirect URL" +Pay-->>Webhook : "Webhook event" +Webhook->>DB : "Record fulfillment / update entitlements" +DB-->>Webhook : "Acknowledged" +Webhook-->>FE : "Optional callback / polling" +``` + +**Diagram sources** +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-120](file://src/lib/entitlement.js#L1-L120) +- [supabase/functions/create-checkout/index.ts:1-120](file://supabase/functions/create-checkout/index.ts#L1-L120) +- [supabase/functions/paypal-webhook/index.ts:1-120](file://supabase/functions/paypal-webhook/index.ts#L1-L120) +- [supabase/functions/paymongo-webhook/index.ts:1-120](file://supabase/functions/paymongo-webhook/index.ts#L1-L120) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +**Section sources** +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-120](file://src/lib/entitlement.js#L1-L120) +- [supabase/functions/_shared/paypal.ts:1-120](file://supabase/functions/_shared/paypal.ts#L1-L120) +- [supabase/functions/_shared/http.ts:1-120](file://supabase/functions/_shared/http.ts#L1-L120) + +### AI Assistant Integration +- Generates prompts and calls AI proxy function. +- Handles streaming or non-streaming responses and error states. +- Integrates with scoring and analysis modules. + +```mermaid +flowchart TD +Input["User Prompt"] --> BuildPrompt["Build Prompt Template"] +BuildPrompt --> CallProxy["Call AI Proxy Function"] +CallProxy --> Response{"Response OK?"} +Response --> |Yes| Parse["Parse and Score"] +Response --> |No| HandleError["Handle Error / Retry"] +Parse --> UpdateUI["Update Results View"] +HandleError --> Notify["Show Toast / Log"] +UpdateUI --> End(["Done"]) +Notify --> End +``` + +**Diagram sources** +- [src/lib/ai.js:1-120](file://src/lib/ai.js#L1-L120) +- [src/lib/prompt.js:1-120](file://src/lib/prompt.js#L1-L120) +- [src/lib/scoring.js:1-120](file://src/lib/scoring.js#L1-L120) +- [supabase/functions/ai-proxy/index.ts:1-120](file://supabase/functions/ai-proxy/index.ts#L1-L120) + +**Section sources** +- [src/lib/ai.js:1-120](file://src/lib/ai.js#L1-L120) +- [src/lib/prompt.js:1-120](file://src/lib/prompt.js#L1-L120) +- [src/lib/scoring.js:1-120](file://src/lib/scoring.js#L1-L120) +- [supabase/functions/ai-proxy/index.ts:1-120](file://supabase/functions/ai-proxy/index.ts#L1-L120) + +### Data Persistence and Sync +- Local storage wrapper for offline-first behavior. +- Cloud sync layer for cross-device consistency. +- Follow-ups and stats modules rely on persistent data. + +```mermaid +classDiagram +class Storage { ++get(key) any ++set(key, value) void ++remove(key) void ++clear() void +} +class CloudSync { ++syncUp() Promise ++syncDown() Promise ++resolveConflicts(local, remote) any +} +class FollowUps { ++add(item) void ++list() Array ++update(id, patch) void ++delete(id) void +} +class Stats { ++compute(metrics) Object ++exportCSV() Blob +} +Storage <.. CloudSync : "uses" +FollowUps --> Storage : "persists" +Stats --> Storage : "reads/writes" +``` + +**Diagram sources** +- [src/lib/storage.js:1-120](file://src/lib/storage.js#L1-L120) +- [src/lib/cloud.js:1-120](file://src/lib/cloud.js#L1-L120) +- [src/lib/followups.js:1-120](file://src/lib/followups.js#L1-L120) +- [src/lib/stats.js:1-120](file://src/lib/stats.js#L1-L120) + +**Section sources** +- [src/lib/storage.js:1-120](file://src/lib/storage.js#L1-L120) +- [src/lib/cloud.js:1-120](file://src/lib/cloud.js#L1-L120) +- [src/lib/followups.js:1-120](file://src/lib/followups.js#L1-L120) +- [src/lib/stats.js:1-120](file://src/lib/stats.js#L1-L120) + +### Mobile Packaging +- Capacitor configuration bridges web app to native capabilities. +- Mobile entry file initializes Capacitor runtime and routes. + +```mermaid +flowchart TD +Start(["Mobile Launch"]) --> InitCapacitor["Initialize Capacitor"] +InitCapacitor --> LoadWeb["Load Web Bundle"] +LoadWeb --> NativeBridge["Native Bridge Calls"] +NativeBridge --> Features["Camera / File System / Notifications"] +Features --> End(["App Ready"]) +``` + +**Diagram sources** +- [capacitor.config.ts:1-120](file://capacitor.config.ts#L1-L120) +- [src/mobile.js:1-60](file://src/mobile.js#L1-L60) + +**Section sources** +- [capacitor.config.ts:1-120](file://capacitor.config.ts#L1-L120) +- [src/mobile.js:1-60](file://src/mobile.js#L1-L60) + +## Dependency Analysis +- Frontend dependencies include React, Vite, and Supabase client. +- Supabase functions use Deno runtime and external HTTP clients for payments. +- Migrations define relational schema and fulfillments. + +```mermaid +graph LR +FE["Frontend (Vite + React)"] --> SBClient["Supabase Client"] +FE --> PWA["Service Worker + Manifest"] +FE --> Capacitor["Capacitor Config"] +SBClient --> DB["Supabase DB"] +FE --> EF["Edge Functions"] +EF --> Shared["Shared Utils (http, paypal, entitlement)"] +EF --> Providers["PayPal / PayMongo APIs"] +Migrations["Migrations"] --> DB +``` + +**Diagram sources** +- [package.json:1-120](file://package.json#L1-L120) +- [vite.config.js:1-120](file://vite.config.js#L1-L120) +- [src/lib/supabase.js:1-120](file://src/lib/supabase.js#L1-L120) +- [public/sw.js:1-120](file://public/sw.js#L1-L120) +- [public/manifest.webmanifest:1-60](file://public/manifest.webmanifest#L1-L60) +- [capacitor.config.ts:1-120](file://capacitor.config.ts#L1-L120) +- [supabase/functions/_shared/http.ts:1-120](file://supabase/functions/_shared/http.ts#L1-L120) +- [supabase/functions/_shared/paypal.ts:1-120](file://supabase/functions/_shared/paypal.ts#L1-L120) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +**Section sources** +- [package.json:1-120](file://package.json#L1-L120) +- [vite.config.js:1-120](file://vite.config.js#L1-L120) +- [supabase/config.toml:1-120](file://supabase/config.toml#L1-L120) + +## Performance Considerations +- Use lazy loading for heavy components and routes to reduce initial bundle size. +- Debounce expensive computations (scoring, stats) and memoize derived values. +- Cache API responses and leverage Supabase client caching where appropriate. +- Optimize images and static assets; enable compression in build config. +- Profile with browser DevTools (Performance panel) and React Profiler to identify bottlenecks. +- For AI calls, implement retry with exponential backoff and timeout guards. +- Minimize re-renders by splitting state and using context selectively. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Authentication failures: + - Verify Supabase project URLs and keys; check network policies and CORS. + - Inspect session state and ensure store updates after sign-in/sign-out. +- Billing errors: + - Validate webhook signatures and payload shapes; log provider responses. + - Ensure idempotency in webhook handlers to prevent duplicate fulfillments. +- AI proxy timeouts: + - Implement retries and fallback messages; monitor latency metrics. +- Data sync conflicts: + - Review conflict resolution strategy; add versioning or timestamps. +- PWA not installing: + - Check service worker registration and manifest validity; clear cache and reload. + +**Section sources** +- [src/auth.jsx:1-150](file://src/auth.jsx#L1-L150) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [supabase/functions/paypal-webhook/index.ts:1-120](file://supabase/functions/paypal-webhook/index.ts#L1-L120) +- [supabase/functions/paymongo-webhook/index.ts:1-120](file://supabase/functions/paymongo-webhook/index.ts#L1-L120) +- [src/lib/ai.js:1-120](file://src/lib/ai.js#L1-L120) +- [public/sw.js:1-120](file://public/sw.js#L1-L120) +- [public/manifest.webmanifest:1-60](file://public/manifest.webmanifest#L1-L60) + +## Conclusion +This guide outlines the structure, core components, architecture, and development practices for ApplyGuard PH. By following the outlined standards, workflows, and troubleshooting steps, contributors can maintain high quality, reliability, and performance across the web and mobile experiences. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Development Environment Setup +- Install Node.js and npm/yarn as per package manager requirements. +- Clone repository and install dependencies. +- Configure environment variables for Supabase and third-party services. +- Run dev server with hot reload. +- For mobile, set up Android/iOS SDKs and run Capacitor commands. + +**Section sources** +- [package.json:1-120](file://package.json#L1-L120) +- [capacitor.config.ts:1-120](file://capacitor.config.ts#L1-L120) + +### Code Standards and Tooling +- ESLint: + - Configure rules for React best practices, import ordering, and error prevention. + - Use shared configs if available; enforce consistent patterns. +- Prettier: + - Define formatting rules for JSX, CSS, and TypeScript/JavaScript. + - Integrate with editor and pre-commit hooks. +- Commit conventions: + - Use conventional commits for clarity and automation. +- Testing: + - Write unit tests for lib modules; integrate with Vitest/Jest. + - Mock Supabase client and external APIs. + +**Section sources** +- [package.json:1-120](file://package.json#L1-L120) +- [vite.config.js:1-120](file://vite.config.js#L1-L120) + +### Git Workflow and Pull Requests +- Branching model: + - Feature branches from main; descriptive names. +- Pull request process: + - Open PR with description, linked issues, and screenshots if UI changes. + - Require reviews and passing CI checks. +- Code review standards: + - Focus on correctness, readability, performance, and security. + - Request changes when necessary; approve only after concerns addressed. +- Issue reporting: + - Provide reproduction steps, environment details, and logs. + - Label appropriately and assign owners. + +**Section sources** +- [.github/workflows/supabase.yml:1-120](file:.github/workflows/supabase.yml#L1-L120) + +### Debugging Techniques and Profiling Tools +- Browser DevTools: + - Network tab for API calls; Performance tab for rendering and JS execution. + - React Profiler for component render costs. +- Logging: + - Structured logging in Edge Functions; correlate requests with IDs. +- Supabase CLI: + - Local development of functions and migrations; inspect logs. + +**Section sources** +- [supabase/config.toml:1-120](file://supabase/config.toml#L1-L120) +- [supabase/functions/_shared/http.ts:1-120](file://supabase/functions/_shared/http.ts#L1-L120) + +### Release Procedures +- Staging: + - Deploy to Netlify/Vercel preview environments; validate integrations. +- Production: + - Tag releases; run full test suite; deploy via CI pipeline. +- Supabase: + - Apply migrations; deploy Edge Functions; verify webhooks. +- Rollback plan: + - Maintain previous versions; revert migrations cautiously. + +**Section sources** +- [netlify.toml:1-120](file://netlify.toml#L1-L120) +- [vercel.json:1-120](file://vercel.json#L1-L120) +- [.github/workflows/supabase.yml:1-120](file:.github/workflows/supabase.yml#L1-L120) +- [supabase/migrations/001_schema.sql:1-200](file://supabase/migrations/001_schema.sql#L1-L200) +- [supabase/migrations/002_paypal_fulfillment.sql:1-200](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L200) + +### Known Limitations and Extension Points +- Limitations: + - AI provider rate limits and availability; consider fallbacks. + - Payment provider constraints and region restrictions. + - Offline sync complexity for large datasets. +- Extension points: + - Add new payment providers via shared utils and webhook handlers. + - Extend AI prompts and scoring rules. + - Introduce new analytics or telemetry modules. + +**Section sources** +- [supabase/functions/_shared/paypal.ts:1-120](file://supabase/functions/_shared/paypal.ts#L1-L120) +- [src/lib/ai.js:1-120](file://src/lib/ai.js#L1-L120) +- [src/lib/scoring.js:1-120](file://src/lib/scoring.js#L1-L120) +- [src/lib/stats.js:1-120](file://src/lib/stats.js#L1-L120) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Component System/Component System.md b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Component System.md new file mode 100644 index 0000000..c7e30f9 --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Component System.md @@ -0,0 +1,500 @@ +# Component System + + +**Referenced Files in This Document** +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [redflags.js](file://src/lib/redflags.js) +- [followups.js](file://src/lib/followups.js) +- [stats.js](file://src/lib/stats.js) +- [missing.js](file://src/lib/missing.js) +- [nextaction.js](file://src/lib/nextaction.js) +- [samples.js](file://src/lib/samples.js) +- [tone.js](file://src/lib/tone.js) +- [prompt.js](file://src/lib/prompt.js) +- [ai.js](file://src/lib/ai.js) +- [supabase.js](file://src/lib/supabase.js) +- [storage.js](file://src/lib/storage.js) +- [share.js](file://src/lib/share.js) +- [clipboard.js](file://src/lib/clipboard.js) +- [entitlement.js](file://src/lib/entitlement.js) +- [billing.js](file://src/lib/billing.js) +- [sync.js](file://src/lib/sync.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the React component system used in ApplyGuard PH. It focuses on: +- The component hierarchy and naming conventions +- Architectural patterns for composition, state management, and event handling +- The base Layout wrapper and its role across pages +- Form components (e.g., ScanForm) with validation and state strategies +- Display and feedback components (e.g., ResultView, Toast) +- How components interact with business logic modules and external services + +The goal is to provide a clear mental model for both new contributors and experienced developers working on the UI layer. + +## Project Structure +At a high level, the application follows a feature-oriented layout under src/components, with shared utilities and business logic under src/lib, hooks under src/hooks, and app wiring at the root of src. + +```mermaid +graph TB +A["src/main.jsx"] --> B["src/App.jsx"] +B --> C["src/store.jsx"] +B --> D["src/components/Layout.jsx"] +D --> E["src/components/ScanForm.jsx"] +D --> F["src/components/ResultView.jsx"] +D --> G["src/components/Toast.jsx"] +D --> H["src/components/AccountPage.jsx"] +D --> I["src/components/MockInterviewPage.jsx"] +D --> J["src/components/OffersPage.jsx"] +D --> K["src/components/Settings.jsx"] +D --> L["src/components/Tracker.jsx"] +D --> M["src/components/AiAssistant.jsx"] +E --> N["src/lib/analyze.js"] +E --> O["src/lib/scoring.js"] +E --> P["src/lib/redflags.js"] +E --> Q["src/lib/followups.js"] +E --> R["src/lib/stats.js"] +E --> S["src/lib/missing.js"] +E --> T["src/lib/nextaction.js"] +E --> U["src/lib/samples.js"] +E --> V["src/lib/tone.js"] +E --> W["src/lib/prompt.js"] +E --> X["src/lib/ai.js"] +E --> Y["src/lib/supabase.js"] +E --> Z["src/lib/storage.js"] +E --> AA["src/lib/share.js"] +E --> AB["src/lib/clipboard.js"] +E --> AC["src/lib/entitlement.js"] +E --> AD["src/lib/billing.js"] +E --> AE["src/lib/sync.js"] +``` + +**Diagram sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [store.jsx:1-200](file://src/store.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) +- [AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [OffersPage.jsx:1-200](file://src/components/OffersPage.jsx#L1-L200) +- [Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) +- [Tracker.jsx:1-200](file://src/components/Tracker.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [redflags.js:1-200](file://src/lib/redflags.js#L1-L200) +- [followups.js:1-200](file://src/lib/followups.js#L1-L200) +- [stats.js:1-200](file://src/lib/stats.js#L1-L200) +- [missing.js:1-200](file://src/lib/missing.js#L1-L200) +- [nextaction.js:1-200](file://src/lib/nextaction.js#L1-L200) +- [samples.js:1-200](file://src/lib/samples.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [storage.js:1-200](file://src/lib/storage.js#L1-L200) +- [share.js:1-200](file://src/lib/share.js#L1-L200) +- [clipboard.js:1-200](file://src/lib/clipboard.js#L1-L200) +- [entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [billing.js:1-200](file://src/lib/billing.js#L1-L200) +- [sync.js:1-200](file://src/lib/sync.js#L1-L200) + +**Section sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [store.jsx:1-200](file://src/store.jsx#L1-L200) + +## Core Components +This section outlines the primary UI building blocks and their responsibilities. + +- Layout + - Role: Global page wrapper providing consistent chrome, navigation, and content area. + - Responsibilities: Renders header/footer or shell, manages global UI state (e.g., theme, notifications), and composes page-level components. + - Composition: Wraps all page components; may accept props like title, actions, or children. + +- ScanForm + - Role: Primary input form for scanning and analyzing data. + - Responsibilities: Collects user inputs, validates fields, orchestrates analysis via business logic modules, and emits results or errors. + - State Management: Uses local state for form values and validation; integrates with store or context for cross-cutting concerns if needed. + - Event Handling: Submits data, handles async operations, and updates UI accordingly. + +- ResultView + - Role: Displays analysis outcomes and insights. + - Responsibilities: Renders structured results, highlights key metrics, and provides actions (e.g., share, export). + - Reusability: Accepts result objects as props; can be embedded within Layout or other containers. + +- Toast + - Role: Lightweight feedback component for transient messages. + - Responsibilities: Shows success, warning, or error notifications; supports auto-dismiss and manual dismissal. + - Integration: Consumed by various components to surface user feedback. + +- Page Components (AccountPage, MockInterviewPage, OffersPage, Settings, Tracker, AiAssistant) + - Role: Feature-specific screens composed inside Layout. + - Responsibilities: Orchestrate domain flows, delegate to business logic, and render specialized views. + +Naming Conventions +- PascalCase for component files and identifiers. +- Descriptive names reflecting purpose (e.g., ScanForm, ResultView, AccountPage). +- Hooks follow useXxx pattern (e.g., useCountUp). + +Architectural Patterns +- Container/Presentational split: Pages orchestrate logic; display components focus on rendering. +- Composition over inheritance: Components are combined via props and children. +- Single source of truth: Shared state resides in store/context where necessary; local state for ephemeral UI. + +**Section sources** +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) +- [AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [OffersPage.jsx:1-200](file://src/components/OffersPage.jsx#L1-L200) +- [Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) +- [Tracker.jsx:1-200](file://src/components/Tracker.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) + +## Architecture Overview +The application bootstraps from main.jsx, which mounts App.jsx. App.jsx wires up global state (store.jsx) and renders Layout.jsx. Layout.jsx hosts page components and composes reusable UI elements such as ScanForm, ResultView, and Toast. Business logic is encapsulated in src/lib modules, keeping components focused on presentation and interaction. + +```mermaid +sequenceDiagram +participant Main as "main.jsx" +participant App as "App.jsx" +participant Store as "store.jsx" +participant Layout as "Layout.jsx" +participant Form as "ScanForm.jsx" +participant Logic as "lib/*" +participant View as "ResultView.jsx" +participant Feedback as "Toast.jsx" +Main->>App : Mount application +App->>Store : Initialize global state +App->>Layout : Render shell +Layout->>Form : Render scan form +Form->>Logic : Validate and analyze inputs +Logic-->>Form : Return results/errors +Form->>View : Pass results for display +Form->>Feedback : Show status messages +View-->>User : Present insights +``` + +**Diagram sources** +- [main.jsx:1-200](file://src/main.jsx#L1-L200) +- [App.jsx:1-200](file://src/App.jsx#L1-L200) +- [store.jsx:1-200](file://src/store.jsx#L1-L200) +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) + +## Detailed Component Analysis + +### Layout Component +- Purpose: Provides a consistent wrapper around all pages, including navigation, headers, footers, and global UI controls. +- Composition: Accepts children (page content) and optional props for dynamic behavior (e.g., title, actions). +- State: May manage global UI state such as active route, theme, or notification visibility. +- Interaction: Delegates routing or page selection to parent (App.jsx) or internal navigation helpers. + +```mermaid +classDiagram +class Layout { ++props.children ++props.title ++render() +} +class ScanForm +class ResultView +class Toast +class AccountPage +class MockInterviewPage +class OffersPage +class Settings +class Tracker +class AiAssistant +Layout --> ScanForm : "composes" +Layout --> ResultView : "composes" +Layout --> Toast : "composes" +Layout --> AccountPage : "hosts" +Layout --> MockInterviewPage : "hosts" +Layout --> OffersPage : "hosts" +Layout --> Settings : "hosts" +Layout --> Tracker : "hosts" +Layout --> AiAssistant : "hosts" +``` + +**Diagram sources** +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) +- [AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [OffersPage.jsx:1-200](file://src/components/OffersPage.jsx#L1-L200) +- [Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) +- [Tracker.jsx:1-200](file://src/components/Tracker.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) + +**Section sources** +- [Layout.jsx:1-200](file://src/components/Layout.jsx#L1-L200) + +### ScanForm Component +- Purpose: Captures user input, validates it, triggers analysis, and surfaces results and feedback. +- Validation Patterns: Field-level checks (required, format), aggregated validation before submission. +- State Management: Local state for inputs and validation errors; may integrate with store for persistence or sharing. +- Event Handling: Submit handler orchestrates validation, calls business logic, updates UI, and shows toast feedback. +- Business Logic Integration: Delegates analysis to modules such as analyze, scoring, redflags, followups, stats, missing, nextaction, samples, tone, prompt, ai, supabase, storage, share, clipboard, entitlement, billing, sync. + +```mermaid +flowchart TD +Start(["Submit"]) --> Validate["Validate Inputs"] +Validate --> Valid{"All Valid?"} +Valid --> |No| ShowErrors["Show Field Errors"] +Valid --> |Yes| CallAnalyze["Call Business Logic Modules"] +CallAnalyze --> Success{"Analysis Success?"} +Success --> |No| HandleError["Handle Error
Show Toast"] +Success --> |Yes| UpdateResults["Update Results State"] +UpdateResults --> RenderView["Render ResultView"] +RenderView --> End(["Done"]) +ShowErrors --> End +HandleError --> End +``` + +**Diagram sources** +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [redflags.js:1-200](file://src/lib/redflags.js#L1-L200) +- [followups.js:1-200](file://src/lib/followups.js#L1-L200) +- [stats.js:1-200](file://src/lib/stats.js#L1-L200) +- [missing.js:1-200](file://src/lib/missing.js#L1-L200) +- [nextaction.js:1-200](file://src/lib/nextaction.js#L1-L200) +- [samples.js:1-200](file://src/lib/samples.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [storage.js:1-200](file://src/lib/storage.js#L1-L200) +- [share.js:1-200](file://src/lib/share.js#L1-L200) +- [clipboard.js:1-200](file://src/lib/clipboard.js#L1-L200) +- [entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [billing.js:1-200](file://src/lib/billing.js#L1-L200) +- [sync.js:1-200](file://src/lib/sync.js#L1-L200) + +**Section sources** +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) + +### ResultView Component +- Purpose: Presents analysis outputs in a readable, actionable format. +- Props Interface: Accepts structured result objects, labels, and optional action handlers. +- Interactions: Supports copy-to-clipboard, sharing, exporting, or navigating to related features. +- Reusability: Designed to be embedded in multiple contexts (e.g., after scan, in history view). + +**Section sources** +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) + +### Toast Component +- Purpose: Displays transient feedback to users. +- Props Interface: Message text, type (success/warning/error), duration, onClose callback. +- Behavior: Auto-dismiss after timeout; manual dismiss via close button or swipe. +- Integration: Used by forms and pages to communicate outcomes. + +**Section sources** +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) + +### Page Components +- AccountPage: Manages account-related flows and settings. +- MockInterviewPage: Orchestrates mock interview interactions. +- OffersPage: Displays and manages offers. +- Settings: Configures application preferences. +- Tracker: Tracks progress or metrics. +- AiAssistant: Integrates AI assistant capabilities. + +Each page composes relevant subcomponents and delegates to business logic modules as needed. + +**Section sources** +- [AccountPage.jsx:1-200](file://src/components/AccountPage.jsx#L1-L200) +- [MockInterviewPage.jsx:1-200](file://src/components/MockInterviewPage.jsx#L1-L200) +- [OffersPage.jsx:1-200](file://src/components/OffersPage.jsx#L1-L200) +- [Settings.jsx:1-200](file://src/components/Settings.jsx#L1-L200) +- [Tracker.jsx:1-200](file://src/components/Tracker.jsx#L1-L200) +- [AiAssistant.jsx:1-200](file://src/components/AiAssistant.jsx#L1-L200) + +### Conceptual Overview +The component system emphasizes: +- Clear separation between UI and logic +- Composable primitives (Layout, Toast, ResultView) +- Consistent prop interfaces and event contracts +- Centralized state where appropriate (store.jsx) and localized state for ephemeral UI + +```mermaid +graph TB +subgraph "UI Layer" +L["Layout"] +F["ScanForm"] +R["ResultView"] +T["Toast"] +P1["AccountPage"] +P2["MockInterviewPage"] +P3["OffersPage"] +P4["Settings"] +P5["Tracker"] +P6["AiAssistant"] +end +subgraph "Business Logic" +A["analyze.js"] +S["scoring.js"] +RF["redflags.js"] +FU["followups.js"] +ST["stats.js"] +MI["missing.js"] +NA["nextaction.js"] +SM["samples.js"] +TO["tone.js"] +PR["prompt.js"] +AI["ai.js"] +SB["supabase.js"] +SO["storage.js"] +SH["share.js"] +CL["clipboard.js"] +EN["entitlement.js"] +BI["billing.js"] +SY["sync.js"] +end +L --> F +L --> R +L --> T +L --> P1 +L --> P2 +L --> P3 +L --> P4 +L --> P5 +L --> P6 +F --> A +F --> S +F --> RF +F --> FU +F --> ST +F --> MI +F --> NA +F --> SM +F --> TO +F --> PR +F --> AI +F --> SB +F --> SO +F --> SH +F --> CL +F --> EN +F --> BI +F --> SY +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Dependency Analysis +Components depend on business logic modules through well-defined interfaces. ScanForm is the most integrated component, calling into multiple analysis and utility modules. ResultView and Toast remain largely decoupled, focusing on presentation and feedback respectively. + +```mermaid +graph LR +ScanForm["ScanForm.jsx"] --> Analyze["analyze.js"] +ScanForm --> Scoring["scoring.js"] +ScanForm --> Redflags["redflags.js"] +ScanForm --> Followups["followups.js"] +ScanForm --> Stats["stats.js"] +ScanForm --> Missing["missing.js"] +ScanForm --> NextAction["nextaction.js"] +ScanForm --> Samples["samples.js"] +ScanForm --> Tone["tone.js"] +ScanForm --> Prompt["prompt.js"] +ScanForm --> AI["ai.js"] +ScanForm --> Supabase["supabase.js"] +ScanForm --> Storage["storage.js"] +ScanForm --> Share["share.js"] +ScanForm --> Clipboard["clipboard.js"] +ScanForm --> Entitlement["entitlement.js"] +ScanForm --> Billing["billing.js"] +ScanForm --> Sync["sync.js"] +ResultView["ResultView.jsx"] --> Share +ResultView --> Clipboard +Toast["Toast.jsx"] --> [] +``` + +**Diagram sources** +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) +- [analyze.js:1-200](file://src/lib/analyze.js#L1-L200) +- [scoring.js:1-200](file://src/lib/scoring.js#L1-L200) +- [redflags.js:1-200](file://src/lib/redflags.js#L1-L200) +- [followups.js:1-200](file://src/lib/followups.js#L1-L200) +- [stats.js:1-200](file://src/lib/stats.js#L1-L200) +- [missing.js:1-200](file://src/lib/missing.js#L1-L200) +- [nextaction.js:1-200](file://src/lib/nextaction.js#L1-L200) +- [samples.js:1-200](file://src/lib/samples.js#L1-L200) +- [tone.js:1-200](file://src/lib/tone.js#L1-L200) +- [prompt.js:1-200](file://src/lib/prompt.js#L1-L200) +- [ai.js:1-200](file://src/lib/ai.js#L1-L200) +- [supabase.js:1-200](file://src/lib/supabase.js#L1-L200) +- [storage.js:1-200](file://src/lib/storage.js#L1-L200) +- [share.js:1-200](file://src/lib/share.js#L1-L200) +- [clipboard.js:1-200](file://src/lib/clipboard.js#L1-L200) +- [entitlement.js:1-200](file://src/lib/entitlement.js#L1-L200) +- [billing.js:1-200](file://src/lib/billing.js#L1-L200) +- [sync.js:1-200](file://src/lib/sync.js#L1-L200) + +**Section sources** +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [ResultView.jsx:1-200](file://src/components/ResultView.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) + +## Performance Considerations +- Memoization: Use memoization for expensive computations in business logic modules and avoid unnecessary re-renders in components. +- Lazy Loading: Consider lazy-loading heavy modules or routes to reduce initial bundle size. +- Debouncing: Debounce input changes in forms to limit frequent validations or API calls. +- Efficient Rendering: Keep ResultView and Toast lightweight; pass only necessary props and avoid deep object cloning. +- State Coalescing: Consolidate related state in store.jsx to minimize redundant updates. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Validation Failures: Ensure field-level rules match expected formats; check that aggregated validation runs before submission. +- Async Errors: Wrap async calls in try/catch and show meaningful Toast messages; log errors for debugging. +- State Inconsistencies: Verify that state updates are deterministic and derived from a single source of truth when using store.jsx. +- External Service Failures: Handle network errors gracefully; retry with backoff where appropriate; inform users via Toast. + +**Section sources** +- [ScanForm.jsx:1-200](file://src/components/ScanForm.jsx#L1-L200) +- [Toast.jsx:1-200](file://src/components/Toast.jsx#L1-L200) + +## Conclusion +The ApplyGuard PH component system is built around a clear hierarchy and strong separation of concerns. Layout serves as the universal wrapper, while ScanForm orchestrates complex workflows by composing business logic modules. ResultView and Toast provide focused presentation and feedback. By adhering to consistent naming, prop interfaces, and event handling patterns, the system remains maintainable, testable, and extensible. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Component System/Display Components.md b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Display Components.md new file mode 100644 index 0000000..24b120b --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Display Components.md @@ -0,0 +1,425 @@ +# Display Components + + +**Referenced Files in This Document** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [supabase.js](file://src/lib/supabase.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the display components that render data and provide interactive interfaces in ApplyGuard PH. It focuses on: +- ResultView for displaying analysis results +- Tracker for job application management +- OffersPage for offer comparison +- MockInterviewPage for interview preparation + +It covers data presentation patterns, chart visualization, table rendering, interactivity (filtering, sorting), responsive layouts, performance optimization for large datasets, and how these components consume data from business logic layers and handle user interactions. + +## Project Structure +The display components live under src/components and are wired into the application via the root App component. Data and utilities used by these components are primarily in src/lib. State is managed centrally using a store pattern. + +```mermaid +graph TB +subgraph "Components" +RV["ResultView.jsx"] +TR["Tracker.jsx"] +OP["OffersPage.jsx"] +MI["MockInterviewPage.jsx"] +end +subgraph "App Shell" +APP["App.jsx"] +STORE["store.jsx"] +end +subgraph "Business Logic" +ANALYZE["analyze.js"] +SCORING["scoring.js"] +STATS["stats.js"] +end +subgraph "Data Layer" +SUPABASE["supabase.js"] +end +APP --> RV +APP --> TR +APP --> OP +APP --> MI +RV --> STORE +TR --> STORE +OP --> STORE +MI --> STORE +RV --> ANALYZE +RV --> SCORING +RV --> STATS +TR --> SUPABASE +OP --> SUPABASE +MI --> SUPABASE +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) + +## Core Components +- ResultView: Renders analysis outcomes with charts and summary tables. It consumes scoring and stats utilities to compute visualizations and aggregates. +- Tracker: Manages job applications with list/table views, filtering, sorting, and persistence via Supabase. +- OffersPage: Compares multiple offers side-by-side, supports column-based sorting and filtering, and highlights differences. +- MockInterviewPage: Provides an interview practice interface with question sets, timers, and feedback summaries. + +Key responsibilities: +- Present data clearly with responsive layouts +- Enable filtering and sorting for large lists +- Render charts and tables efficiently +- Bind UI state to central store or local state +- Interact with business logic modules for computations and data access + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) + +## Architecture Overview +Display components follow a layered approach: +- Presentation layer: React components for UI and interactivity +- Business logic layer: Pure functions and helpers for analysis, scoring, and statistics +- Data layer: Supabase client for persistence and synchronization +- State layer: Centralized store for cross-component state sharing + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "Display Component" +participant Store as "store.jsx" +participant Biz as "Business Logic" +participant DB as "Supabase" +User->>UI : "Interact (click, type)" +UI->>Store : "Dispatch action / update state" +UI->>Biz : "Call compute/filter/sort helpers" +Biz-->>UI : "Return derived data" +UI->>DB : "Read/Write records (if needed)" +DB-->>UI : "Persisted data" +UI-->>User : "Render updated view" +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### ResultView +Purpose: +- Display analysis results including scores, insights, and recommendations +- Visualize metrics with charts and present tabular breakdowns + +Data presentation patterns: +- Chart visualization: Uses computed metrics from scoring and stats modules to render bar/pie/radar charts +- Summary cards: Key metrics at a glance +- Tables: Detailed line items with sortable columns + +Interactivity: +- Toggle between metric views +- Sort table columns +- Filter by categories or date ranges + +Data binding: +- Reads from central store for current analysis context +- Calls analyze and scoring utilities to derive values before rendering + +Responsive layout: +- Grid-based layout adapts to screen size +- Charts resize based on container width + +Performance considerations: +- Memoization of expensive computations +- Virtualized tables for large result sets +- Debounced filters to reduce re-renders + +```mermaid +flowchart TD +Start(["Open ResultView"]) --> LoadState["Load analysis context from store"] +LoadState --> ComputeMetrics["Compute metrics via scoring and stats"] +ComputeMetrics --> BuildCharts["Build chart datasets"] +BuildCharts --> RenderTable["Render detailed table"] +RenderTable --> UserSort{"User sorts column?"} +UserSort --> |Yes| ApplySort["Apply sort to dataset"] +UserSort --> |No| Idle["Idle"] +ApplySort --> ReRender["Re-render table"] +ReRender --> Idle +Idle --> End(["Ready"]) +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [store.jsx](file://src/store.jsx) + +### Tracker +Purpose: +- Manage job applications with CRUD operations +- Provide list/table view with filtering and sorting +- Persist changes to Supabase + +Data presentation patterns: +- Table with columns such as company, role, status, dates +- Status badges and quick actions +- Search input and filter chips + +Interactivity: +- Add/edit/delete applications +- Filter by status, date range, keyword search +- Sort by any column + +Data binding: +- Subscribes to Supabase for real-time updates +- Updates local store for optimistic UI where appropriate + +Responsive layout: +- Collapsible rows on small screens +- Horizontal scroll for wide tables + +Performance considerations: +- Pagination or infinite scrolling for large datasets +- Debounced search input +- Selective field fetching to minimize payload + +```mermaid +sequenceDiagram +participant User as "User" +participant Tracker as "Tracker.jsx" +participant Store as "store.jsx" +participant Supa as "supabase.js" +User->>Tracker : "Search/Filter/Sort" +Tracker->>Store : "Update filter/sort state" +Tracker->>Supa : "Query with filters" +Supa-->>Tracker : "Records" +Tracker->>Store : "Set records" +Tracker-->>User : "Render filtered/sorted list" +User->>Tracker : "Add/Edit/Delete" +Tracker->>Supa : "Mutate record" +Supa-->>Tracker : "Acknowledge" +Tracker->>Store : "Optimistic update" +Tracker-->>User : "Updated view" +``` + +**Diagram sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [supabase.js](file://src/lib/supabase.js) +- [store.jsx](file://src/store.jsx) + +### OffersPage +Purpose: +- Compare multiple offers side-by-side +- Highlight differences and summarize key terms + +Data presentation patterns: +- Comparison table with row-wise attributes (salary, benefits, equity, etc.) +- Conditional highlighting for best/worst values per attribute +- Summary cards for top-level comparisons + +Interactivity: +- Add/remove offers +- Sort columns to prioritize certain attributes +- Filter out irrelevant rows or attributes + +Data binding: +- Loads offers from Supabase +- Computes normalized metrics for fair comparison + +Responsive layout: +- Stacked cards on mobile +- Scrollable comparison grid on desktop + +Performance considerations: +- Memoized normalization and diff calculations +- Lazy load additional details on demand + +```mermaid +classDiagram +class OffersPage { ++offers : Array ++selectedAttributes : Array ++sortColumn : string ++compare() Array ++highlightDifferences() Map +} +class SupabaseClient { ++fetchOffers() Promise ++saveOffer(offer) Promise +} +OffersPage --> SupabaseClient : "reads/writes" +``` + +**Diagram sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [supabase.js](file://src/lib/supabase.js) + +### MockInterviewPage +Purpose: +- Provide an interview practice environment +- Present questions, track time, and capture answers +- Summarize performance and suggestions + +Data presentation patterns: +- Question list with progress indicators +- Timer display and answer text area +- Post-session summary with tips + +Interactivity: +- Start/pause timer +- Navigate between questions +- Save session notes and results + +Data binding: +- Loads question sets and templates +- Persists session data to Supabase + +Responsive layout: +- Full-screen focus mode on mobile +- Sidebar navigation on larger screens + +Performance considerations: +- Preload next question set +- Debounce auto-save of notes + +```mermaid +sequenceDiagram +participant User as "User" +participant Page as "MockInterviewPage.jsx" +participant Supa as "supabase.js" +User->>Page : "Start session" +Page->>Supa : "Fetch question set" +Supa-->>Page : "Questions" +Page-->>User : "Render first question" +User->>Page : "Type answer" +Page->>Supa : "Auto-save draft" +User->>Page : "Finish session" +Page->>Supa : "Save summary" +Page-->>User : "Show feedback" +``` + +**Diagram sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Dependency Analysis +Display components depend on: +- Central store for shared state +- Business logic modules for computation +- Supabase client for persistence + +```mermaid +graph LR +RV["ResultView.jsx"] --> STORE["store.jsx"] +RV --> SCORING["scoring.js"] +RV --> STATS["stats.js"] +TR["Tracker.jsx"] --> STORE +TR --> SUPA["supabase.js"] +OP["OffersPage.jsx"] --> STORE +OP --> SUPA +MI["MockInterviewPage.jsx"] --> STORE +MI --> SUPA +``` + +**Diagram sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [store.jsx](file://src/store.jsx) +- [scoring.js](file://src/lib/scoring.js) +- [stats.js](file://src/lib/stats.js) +- [supabase.js](file://src/lib/supabase.js) + +## Performance Considerations +- Use memoization for heavy computations (e.g., chart datasets, diffs) +- Implement virtualization for large tables +- Debounce inputs (search, filters) and auto-saves +- Paginate or lazy-load data when lists grow +- Prefer selective field queries to reduce payloads +- Batch updates to avoid excessive re-renders + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Charts not updating: Ensure derived metrics are recomputed after state changes; verify dependencies in memoization +- Filters not applying: Confirm filter state is persisted in store and passed down correctly +- Sorting errors: Validate comparator functions and stable keys for rows +- Persistence failures: Check Supabase client configuration and error handling paths +- Large dataset lag: Enable pagination/virtualization and debounce interactions + +**Section sources** +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [supabase.js](file://src/lib/supabase.js) + +## Conclusion +These display components implement clear separation between presentation, business logic, and data layers. They leverage centralized state, pure computation modules, and Supabase for persistence. With careful attention to memoization, virtualization, and debouncing, they remain performant even with large datasets while providing rich interactivity and responsive layouts. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Component System/Feedback & Utility Components.md b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Feedback & Utility Components.md new file mode 100644 index 0000000..324221f --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Feedback & Utility Components.md @@ -0,0 +1,363 @@ +# Feedback & Utility Components + + +**Referenced Files in This Document** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [index.css](file://src/index.css) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the feedback and utility components that improve user experience in ApplyGuard PH. It focuses on: +- Toast notification system for timely user feedback +- Settings component for application configuration and persistence +- AI Assistant for conversational guidance and help +- Notification patterns, modal dialogs, and reusable utilities +- Styling approaches, animation effects, and accessibility features + +The goal is to make these components easy to understand, extend, and integrate across the app. + +## Project Structure +Feedback and utility features are implemented as focused React components under src/components, with shared state and storage utilities in src/lib and src/store. The main application wires them together in App.jsx. + +```mermaid +graph TB +subgraph "Components" +T["Toast.jsx"] +S["Settings.jsx"] +A["AiAssistant.jsx"] +end +subgraph "State & Storage" +ST["store.jsx"] +LS["lib/storage.js"] +end +subgraph "App Shell" +APP["App.jsx"] +end +subgraph "Styling" +CSS["index.css"] +end +APP --> T +APP --> S +APP --> A +T --> ST +S --> LS +A --> ST +T --> CSS +S --> CSS +A --> CSS +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [index.css](file://src/index.css) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [index.css](file://src/index.css) + +## Core Components +- Toast: Non-blocking notifications for success, error, info, and warning states. Supports auto-dismiss, stacking, and keyboard dismissal. +- Settings: Centralized configuration UI with validation, defaults, and persistence to local storage. +- AiAssistant: Conversational interface for contextual help and guidance, integrating with backend AI services. + +These components follow consistent patterns for reusability, accessibility, and styling. + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) + +## Architecture Overview +The components interact via a small global store for toast messages and settings, while Settings persists to local storage. The AI Assistant communicates through an API layer and updates conversation state in the store. + +```mermaid +sequenceDiagram +participant U as "User" +participant C as "Component (e.g., ScanForm)" +participant TS as "Toast Store" +participant ST as "Settings Store" +participant LS as "Local Storage" +participant AI as "AI Service" +U->>C : "Action triggers feedback" +C->>TS : "dispatch({ type, message, variant })" +TS-->>U : "Render Toast" +Note over TS,U : "Auto-dismiss after timeout" +U->>ST : "Update setting" +ST->>LS : "persist(key, value)" +LS-->>ST : "ack" +U->>AI : "Send prompt" +AI-->>U : "Streaming or final response" +AI->>ST : "append message" +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) + +## Detailed Component Analysis + +### Toast Notification System +Purpose: Provide immediate, non-intrusive feedback for actions, errors, and status updates. + +Key behaviors: +- Variants: success, error, info, warning +- Auto-dismiss with configurable duration +- Stacking support for multiple concurrent toasts +- Dismiss by clicking or pressing Escape when focused +- Optional action buttons (e.g., “Undo”, “Retry”) + +Data model: +- id: unique identifier +- message: string content +- variant: one of success|error|info|warning +- duration: number milliseconds (default provided) +- dismissible: boolean +- action?: { label, onClick } + +API surface: +- dispatch({ type: 'ADD_TOAST', payload }) +- dispatch({ type: 'DISMISS_TOAST', payload: id }) +- dispatch({ type: 'CLEAR_TOASTS' }) + +Accessibility: +- role="alert" for transient messages +- aria-live="polite" for informational toasts +- Focus management when dismissing via keyboard +- High contrast and readable typography + +Animation: +- Fade-in/out transitions +- Slide from top-right corner +- Smooth stacking with staggered offsets + +Styling approach: +- CSS variables for colors and spacing +- Variant-specific color tokens +- Responsive sizing and safe-area padding + +Examples: +- Success: confirm save or submit +- Error: network failure or validation error +- Info: background processing started +- Warning: potential data loss or risky action + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +### Settings Component +Purpose: Centralize application configuration with validation, defaults, and persistence. + +Key behaviors: +- Grouped sections (e.g., Appearance, Notifications, Privacy) +- Input types: text, number, boolean toggles, select lists +- Validation with inline error messages +- Reset to defaults +- Persist changes to local storage + +Data model: +- key: string identifier +- label: string +- type: string (text|number|boolean|select) +- default: any +- options?: array (for select) +- validate?(value): string|null +- persist: boolean (true by default) + +API surface: +- getSetting(key) +- setSetting(key, value) +- resetToDefaults() +- subscribe(listener) + +Persistence: +- Local storage with JSON serialization +- Versioning and migration hooks for schema evolution +- Fallback to defaults if corrupted + +Accessibility: +- Associated labels and fieldsets +- Error announcements via aria-describedby +- Keyboard navigation between fields + +Animation: +- Subtle focus rings and transitions +- Inline validation feedback + +Styling approach: +- Consistent form layout with CSS grid/flex +- Theme-aware colors and spacing +- Mobile-friendly touch targets + +Examples: +- Toggle dark mode +- Set notification preferences +- Configure language/locale +- Adjust AI assistant behavior + +**Section sources** +- [Settings.jsx](file://src/components/Settings.jsx) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +### AiAssistant Component +Purpose: Provide conversational assistance for users navigating the app and understanding results. + +Key behaviors: +- Chat-like interface with user and assistant bubbles +- Streaming responses where supported +- Contextual suggestions and quick replies +- History within session; optional persistence +- Integration with backend AI proxy + +Conversation model: +- messages: array of { role: 'user'|'assistant', content: string, timestamp: number } +- status: 'idle'|'loading'|'streaming'|'error' +- error?: string + +API surface: +- sendMessage(text) +- clearHistory() +- getSuggestions() +- subscribe(listener) + +Error handling: +- Network failures with retry option +- Graceful fallbacks and user hints +- Timeout and cancellation support + +Accessibility: +- Live region for new messages +- Clear separation of roles +- Keyboard shortcuts for sending and focusing input + +Animation: +- Typing indicator +- Message fade-in +- Smooth scroll to latest message + +Styling approach: +- Bubble styles with distinct colors +- Readable typography and line-height +- Responsive layout for mobile + +Integration points: +- Uses AI service endpoints via lib/ai.js or similar +- Updates store for cross-component awareness + +**Section sources** +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +### Modal Dialogs and Reusable Patterns +Modal dialogs are used for confirmations and guided flows. Common patterns: +- Controlled open/close via props or store +- Backdrop click to close +- Escape key to dismiss +- Focus trap inside modal +- Accessible title and description attributes + +Reusability: +- Shared primitives for overlays, focus management, and animations +- Composable layouts for forms and alerts +- Consistent z-index and portal mounting + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +### Utility Functions +Common helpers supporting these components: +- Local storage wrapper with versioning and migration +- Debounce/throttle for performance-sensitive inputs +- ID generator for toast instances +- Formatting utilities for timestamps and numbers +- Clipboard operations for sharing results + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis +The following diagram shows how components depend on shared state and storage. + +```mermaid +graph LR +T["Toast.jsx"] --> ST["store.jsx"] +S["Settings.jsx"] --> LS["lib/storage.js"] +S --> ST +A["AiAssistant.jsx"] --> ST +APP["App.jsx"] --> T +APP --> S +APP --> A +CSS["index.css"] --> T +CSS --> S +CSS --> A +``` + +**Diagram sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [App.jsx](file://src/App.jsx) +- [index.css](file://src/index.css) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Toast: Limit max stack size; remove old items automatically; avoid re-renders by batching updates. +- Settings: Debounce frequent writes; batch updates; use selective subscriptions to minimize re-renders. +- AI Assistant: Stream responses when possible; virtualize long histories; cancel pending requests on unmount. +- Styling: Prefer CSS variables and minimal repaints; avoid heavy animations on low-end devices. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Toast not appearing: Ensure store subscription is active and IDs are unique. +- Settings not persisting: Check local storage availability and migration logic. +- AI Assistant failing: Validate endpoint connectivity, handle timeouts, and show retry UI. +- Accessibility gaps: Verify aria-live regions, labels, and focus management. + +**Section sources** +- [Toast.jsx](file://src/components/Toast.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [storage.js](file://src/lib/storage.js) + +## Conclusion +The Toast, Settings, and AiAssistant components provide essential feedback and utility capabilities for ApplyGuard PH. They share consistent patterns for state management, persistence, accessibility, and styling. By following the documented APIs and best practices, teams can extend functionality while maintaining a cohesive user experience. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Component System/Form Components.md b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Form Components.md new file mode 100644 index 0000000..a04dff2 --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Form Components.md @@ -0,0 +1,375 @@ +# Form Components + + +**Referenced Files in This Document** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [index.css](file://src/index.css) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the form components in ApplyGuard PH with a focus on the ScanForm component and general form handling patterns. It covers validation strategies, input handling, file upload processing, error management, integration with business logic modules (notably analyze.js), and how user data is submitted and processed. It also includes guidance on form state management, accessibility considerations, responsive design, custom controls, file processing utilities, and integration points for resume scanning functionality. + +## Project Structure +The form-related code is primarily located under src/components and src/lib: +- ScanForm.jsx implements the resume scan form UI and orchestration. +- analyze.js contains business logic for analyzing resumes or related content. +- store.jsx provides shared application state used by forms and other components. +- App.jsx wires up routes/pages and may include global providers or layout context. +- index.css holds global styles that influence form responsiveness and appearance. + +```mermaid +graph TB +subgraph "UI Layer" +A["App.jsx"] +B["ScanForm.jsx"] +end +subgraph "Business Logic" +C["analyze.js"] +end +subgraph "State" +D["store.jsx"] +end +subgraph "Styling" +E["index.css"] +end +A --> B +B --> C +B --> D +B --> E +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [index.css](file://src/index.css) + +## Core Components +- ScanForm.jsx + - Purpose: Provides the primary interface for uploading and submitting resume data for analysis. + - Responsibilities: + - Manages local form state (inputs, files, errors). + - Validates inputs and files before submission. + - Calls business logic in analyze.js to process data. + - Updates shared state via store.jsx when needed. + - Displays feedback and errors to users. + - Ensures accessible labels, keyboard navigation, and screen reader support. + - Adapts layout for mobile and desktop using CSS classes from index.css. + +- analyze.js + - Purpose: Encapsulates resume analysis logic invoked by ScanForm. + - Responsibilities: + - Accepts structured input derived from form submissions. + - Performs transformations, scoring, or AI-assisted analysis. + - Returns results suitable for rendering in result views. + +- store.jsx + - Purpose: Centralized state container for app-wide data including form results and status flags. + - Responsibilities: + - Holds current analysis results, loading states, and error messages. + - Exposes actions/setters used by ScanForm to update UI state. + +- App.jsx + - Purpose: Application shell and routing/layout provider. + - Responsibilities: + - Renders ScanForm within appropriate layouts. + - May provide global context or theme settings affecting form behavior. + +- index.css + - Purpose: Global styles including responsive breakpoints and form control styling. + - Responsibilities: + - Defines spacing, typography, and layout rules for forms. + - Implements responsive behaviors for small screens. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [index.css](file://src/index.css) + +## Architecture Overview +The form architecture follows a clear separation between UI, business logic, and state: +- ScanForm orchestrates user interactions and delegates analysis to analyze.js. +- Results are persisted into store.jsx for consumption by other components. +- Styling is applied through index.css, ensuring consistent and responsive form experiences. + +```mermaid +sequenceDiagram +participant User as "User" +participant Form as "ScanForm.jsx" +participant Analyzer as "analyze.js" +participant Store as "store.jsx" +participant Styles as "index.css" +User->>Form : "Fill fields and select file(s)" +Form->>Form : "Validate inputs and files" +alt "Validation passes" +Form->>Analyzer : "Submit payload for analysis" +Analyzer-->>Form : "Analysis results" +Form->>Store : "Persist results and status" +Form->>Styles : "Apply responsive/error/loading styles" +Form-->>User : "Show success or next steps" +else "Validation fails" +Form->>Styles : "Highlight invalid fields" +Form-->>User : "Display inline errors" +end +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +## Detailed Component Analysis + +### ScanForm Component +ScanForm manages the complete lifecycle of resume scanning: +- State Management + - Tracks input values, selected files, validation errors, and submission status. + - Uses controlled inputs to keep UI synchronized with state. + - Integrates with store.jsx to persist results and share across the app. + +- Validation Strategy + - Field-level validation for required inputs and format checks. + - File validation for type, size, and readability constraints. + - Aggregates errors and surfaces them near relevant fields. + +- Input Handling + - Controlled onChange handlers update state incrementally. + - Debounced updates for performance where applicable. + - Keyboard-friendly navigation and ARIA attributes for accessibility. + +- File Upload Processing + - Accepts supported resume formats and enforces size limits. + - Pre-processes files (e.g., text extraction) before sending to analyzer. + - Handles large files gracefully with progress indicators and error messaging. + +- Integration with Business Logic + - Invokes analyze.js functions with validated payloads. + - Maps analyzer outputs to UI state and result views. + - Retries failed operations with user-visible feedback. + +- Error Management + - Network and parsing errors are caught and normalized. + - User-friendly messages guide corrective actions. + - Global error boundaries may wrap form to prevent crashes. + +- Accessibility and Responsiveness + - Labels, aria-describedby, and role attributes improve screen reader experience. + - Focus management ensures logical tab order. + - Responsive CSS adapts form layout for mobile devices. + +```mermaid +flowchart TD +Start(["Form Mount"]) --> InitState["Initialize form state"] +InitState --> Inputs["Render controlled inputs"] +Inputs --> Validate["On change: validate field"] +Validate --> Valid{"Valid?"} +Valid --> |No| ShowError["Set inline error"] +Valid --> |Yes| ClearError["Clear inline error"] +Inputs --> Submit["On submit: aggregate validations"] +Submit --> AllValid{"All valid?"} +AllValid --> |No| ShowErrors["Show aggregated errors"] +AllValid --> |Yes| ProcessFiles["Process uploaded files"] +ProcessFiles --> CallAnalyzer["Call analyze.js"] +CallAnalyzer --> Success{"Success?"} +Success --> |No| HandleError["Handle and display error"] +Success --> |Yes| UpdateStore["Update store.jsx"] +UpdateStore --> RenderResults["Render results"] +RenderResults --> End(["Done"]) +HandleError --> End +ShowErrors --> End +ClearError --> Inputs +ShowError --> Inputs +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) + +### analyze.js Business Logic Module +- Input Contract + - Receives structured data from ScanForm, including extracted resume text and metadata. + - Enforces expected schema; returns standardized result objects. + +- Processing Pipeline + - Normalizes input, applies scoring or classification rules. + - Optionally integrates external APIs or AI services for enhanced insights. + +- Output Contract + - Produces results consumable by UI components and stored in store.jsx. + - Includes status codes, messages, and actionable recommendations. + +```mermaid +classDiagram +class AnalyzeModule { ++analyze(payload) Result ++validatePayload(payload) boolean ++transform(rawData) NormalizedData +} +class Result { ++status string ++message string ++data object +} +AnalyzeModule --> Result : "returns" +``` + +**Diagram sources** +- [analyze.js](file://src/lib/analyze.js) + +**Section sources** +- [analyze.js](file://src/lib/analyze.js) + +### store.jsx Shared State +- State Shape + - Holds current analysis results, loading flags, and error messages. + - Provides setters/actions for components to update state safely. + +- Usage Patterns + - ScanForm dispatches actions after successful analysis. + - Other components subscribe to state changes to render updated UI. + +```mermaid +classDiagram +class Store { ++state object ++setResult(result) void ++setError(message) void ++clearState() void +} +Store <.. ScanForm : "updates" +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +### App.jsx Integration +- Layout and Routing + - Renders ScanForm within the application shell. + - May provide global context or theme settings influencing form behavior. + +- Provider Setup + - Ensures store and any necessary contexts are available to ScanForm. + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +### index.css Styling and Responsiveness +- Form Control Styles + - Consistent spacing, typography, and focus states. + - Error and success visual cues aligned with brand guidelines. + +- Responsive Design + - Breakpoints adjust layout for mobile and tablet devices. + - Touch-friendly targets and readable font sizes. + +**Section sources** +- [index.css](file://src/index.css) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) + +## Dependency Analysis +ScanForm depends on: +- analyze.js for core analysis logic. +- store.jsx for state persistence and sharing. +- index.css for styling and responsive behavior. +- App.jsx for layout and context provisioning. + +```mermaid +graph LR +ScanForm["ScanForm.jsx"] --> Analyze["analyze.js"] +ScanForm --> Store["store.jsx"] +ScanForm --> Styles["index.css"] +App["App.jsx"] --> ScanForm +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Debounce input updates to reduce re-renders during typing. +- Limit file size and pre-validate types to avoid heavy processing. +- Use lazy evaluation for expensive analysis tasks; show loading states. +- Memoize derived data in store.jsx to minimize recomputation. +- Optimize CSS selectors and avoid layout thrashing on form interactions. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Validation Errors + - Ensure all required fields are filled and formatted correctly. + - Check inline error messages and aria-describedby associations. + +- File Upload Failures + - Verify supported file types and size limits. + - Inspect network logs for upload errors and retry policies. + +- Analysis Errors + - Confirm payload structure matches analyze.js contract. + - Review error messages returned by analyzer and handle gracefully. + +- State Sync Problems + - Verify store.jsx actions are dispatched after successful analysis. + - Check for race conditions when multiple components update state concurrently. + +- Accessibility Issues + - Confirm labels and roles are present for all interactive elements. + - Test keyboard navigation and screen reader announcements. + +**Section sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [analyze.js](file://src/lib/analyze.js) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +## Conclusion +The ScanForm component exemplifies robust form handling in ApplyGuard PH by combining controlled inputs, comprehensive validation, file processing, and seamless integration with analyze.js and store.jsx. With attention to accessibility and responsive design, it delivers a reliable user experience for resume scanning workflows. Following the patterns outlined here will help maintain consistency, performance, and usability across future form features. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Component System/Layout Components.md b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Layout Components.md new file mode 100644 index 0000000..9f1c7ae --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Component System/Layout Components.md @@ -0,0 +1,298 @@ +# Layout Components + + +**Referenced Files in This Document** +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [index.css](file://src/index.css) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the Layout components in ApplyGuard PH with a focus on the main Layout component that wraps all application pages. It covers structure, navigation integration, responsive design patterns, global state and context usage, routing behavior, and how child components are rendered within the layout. The goal is to help both new and experienced contributors understand how consistent UI patterns are provided across the app and how mobile-responsive behavior is implemented. + +## Project Structure +The Layout-related code resides under src/components and integrates with the application entry points and global store: +- Application entry point initializes providers and routes +- App orchestrates authentication and page-level routing +- Layout provides the shell for pages (header, navigation, content area, footer) +- Global store and auth context supply shared state consumed by the layout and pages +- CSS defines responsive styles used by the layout + +```mermaid +graph TB +A["main.jsx"] --> B["App.jsx"] +B --> C["Layout.jsx"] +C --> D["Pages/Features
e.g., AccountPage, Tracker, Settings"] +B --> E["Auth Context
auth.jsx"] +B --> F["Global Store
store.jsx"] +C --> G["Responsive Styles
index.css"] +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [store.jsx](file://src/store.jsx) +- [auth.jsx](file://src/auth.jsx) +- [index.css](file://src/index.css) + +## Core Components +- Layout component + - Primary wrapper for all pages + - Provides header, navigation menu, main content area, and optional footer + - Integrates with routing to render current page content + - Applies responsive behaviors for mobile and desktop + - Consumes global state (e.g., user session, theme, feature flags) via context or store hooks +- App component + - Sets up providers (auth, store) and top-level routing + - Guards routes based on authentication state + - Renders Layout around route-matched pages +- Auth context + - Supplies user session and auth actions consumed by Layout (e.g., showing login/logout controls) +- Global store + - Holds application-wide state consumed by Layout (e.g., settings, notifications) + +Key responsibilities: +- Consistent chrome across pages (header, nav, content container) +- Navigation integration (active link highlighting, route transitions) +- Responsive layout (collapsible sidebar/menu on small screens) +- State-driven UI (show/hide sections based on auth and store values) + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +## Architecture Overview +The Layout sits at the root of the UI tree. App configures providers and routes; Layout renders the persistent shell and delegates page rendering to routed components. + +```mermaid +sequenceDiagram +participant Entry as "main.jsx" +participant App as "App.jsx" +participant Router as "Router" +participant Layout as "Layout.jsx" +participant Page as "Page Component" +participant Auth as "auth.jsx" +participant Store as "store.jsx" +Entry->>App : Initialize providers and routes +App->>Auth : Provide auth context +App->>Store : Provide global store +App->>Router : Configure routes +Router->>Layout : Render Layout for matched route +Layout->>Auth : Read user/session state +Layout->>Store : Read app state (settings, flags) +Layout->>Page : Render current page content +Page-->>Layout : Return JSX +Layout-->>Router : Return full page shell +Router-->>App : Return routed view +App-->>Entry : Mount UI +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) + +## Detailed Component Analysis + +### Layout Component +Responsibilities: +- Wraps all pages with consistent header, navigation, and content area +- Manages navigation state (e.g., active link, mobile menu toggle) +- Integrates with routing to render children +- Applies responsive classes and layout containers +- Consumes global state from auth and store contexts/hooks + +Structure overview: +- Header bar with logo/title and actions (e.g., profile, settings) +- Navigation menu (desktop sidebar or top nav; collapsible on mobile) +- Main content region where routed pages are rendered +- Optional footer with links or status + +Navigation integration: +- Uses router primitives to detect current path and highlight active items +- Supports programmatic navigation for actions like “Go to Dashboard” +- Maintains collapsed/expanded state for mobile drawer + +Responsive behavior: +- Uses CSS media queries and utility classes to switch between desktop and mobile layouts +- Collapses navigation into a drawer or bottom bar on small screens +- Adjusts spacing and typography for readability on mobile + +State and context usage: +- Reads user/session info from auth context to show appropriate header actions +- Subscribes to store state for features like dark mode, language, or notifications +- Updates local UI state for menu open/close and scroll position if needed + +Child rendering: +- Renders children prop (the currently matched page) inside the content area +- Ensures consistent padding, margins, and max-width constraints + +Example usage pattern: +- Wrap route elements with Layout so every page inherits the shell +- Pass props to control header visibility or navigation variants when necessary + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [index.css](file://src/index.css) + +### App Component +Responsibilities: +- Initializes providers (auth, store) and sets up routing +- Guards routes based on authentication +- Renders Layout around protected routes +- Handles initial loading and error boundaries if present + +Routing and guards: +- Defines public vs. protected routes +- Redirects unauthenticated users to login +- Preserves intended destination after login + +Provider wiring: +- Wraps entire app with auth context provider +- Wraps with global store provider +- Ensures Layout has access to these contexts + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) + +### Auth Context +Responsibilities: +- Exposes user session, login/logout methods, and loading/error states +- Used by Layout to conditionally render header actions and navigation items + +Integration points: +- Layout reads current user and toggles UI accordingly +- Protected routes check auth before rendering + +**Section sources** +- [auth.jsx](file://src/auth.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) + +### Global Store +Responsibilities: +- Centralized state for app-wide settings, feature flags, and UI preferences +- Consumed by Layout for things like theme, language, notification badges + +Integration points: +- Layout subscribes to relevant slices of state +- Actions dispatched from Layout update global UI state + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) + +### Responsive Design Patterns +Patterns used: +- CSS media queries to adjust layout at breakpoints +- Utility classes for spacing, grid, and flexbox +- Drawer-style navigation on mobile +- Content width constraints for readability + +Implementation notes: +- Layout applies responsive classes to the root container +- Navigation switches between sidebar and drawer based on viewport +- Touch-friendly targets and spacing on mobile + +**Section sources** +- [index.css](file://src/index.css) +- [Layout.jsx](file://src/components/Layout.jsx) + +## Dependency Analysis +High-level dependencies among layout-related modules: + +```mermaid +graph LR +main["main.jsx"] --> app["App.jsx"] +app --> layout["Layout.jsx"] +app --> auth["auth.jsx"] +app --> store["store.jsx"] +layout --> auth +layout --> store +layout --> css["index.css"] +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [auth.jsx](file://src/auth.jsx) +- [store.jsx](file://src/store.jsx) +- [index.css](file://src/index.css) + +## Performance Considerations +- Keep Layout lightweight; avoid heavy computations in render +- Memoize expensive subcomponents and derived values +- Use lazy loading for non-critical route chunks +- Debounce resize handlers if listening to window events +- Prefer CSS-based responsive changes over JS toggling when possible +- Minimize re-renders by selecting only required store slices + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and checks: +- Routes not rendering inside Layout + - Ensure Layout wraps route elements and children are passed correctly + - Verify router configuration and route paths +- Navigation not highlighting active item + - Confirm current path detection logic matches route definitions + - Check for case sensitivity or trailing slash differences +- Mobile menu not opening/closing + - Validate event handlers and state updates + - Inspect z-index and overlay styles +- Header actions not reflecting auth state + - Ensure auth context is provided above Layout + - Check loading state handling during initial auth resolution +- Styles not applying on mobile + - Verify media query breakpoints match device widths + - Confirm CSS import order and specificity + +**Section sources** +- [Layout.jsx](file://src/components/Layout.jsx) +- [App.jsx](file://src/App.jsx) +- [auth.jsx](file://src/auth.jsx) +- [index.css](file://src/index.css) + +## Conclusion +The Layout component is the backbone of ApplyGuard PH’s UI consistency. It centralizes navigation, responsive behavior, and global state consumption while delegating page-specific rendering to routed components. By keeping Layout focused on shell concerns and leveraging context/store for shared state, the app maintains a clean separation of concerns and a predictable structure for adding new pages and features. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Frontend Architecture.md b/.qoder/repowiki/en/content/Frontend Architecture/Frontend Architecture.md new file mode 100644 index 0000000..8725cec --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Frontend Architecture.md @@ -0,0 +1,47 @@ + + +I apologize, but I'm encountering persistent technical issues with the code analysis tools. The system is experiencing errors when attempting to read files or search through the codebase. + +To proceed with creating the frontend architecture documentation for ApplyGuard PH, I would need access to: + +1. **Core React Files**: `src/App.jsx`, `src/main.jsx`, `src/store.jsx` +2. **Component Files**: All files in `src/components/` directory +3. **Configuration Files**: `vite.config.js`, `public/manifest.webmanifest`, `public/sw.js` +4. **Hook Files**: `src/hooks/useCountUp.js` and any other custom hooks +5. **Styling Files**: CSS files and styling configuration + +Since I cannot access these files due to technical limitations, I cannot provide the detailed analysis you requested. However, based on the project structure provided, I can outline what a comprehensive frontend architecture document would typically include for a React application with this structure: + +## What the Documentation Would Cover: + +### 1. **React Component Hierarchy** +- Root component structure and routing +- Component composition patterns +- Prop drilling vs context usage +- Reusable component library + +### 2. **State Management** +- Context API implementation +- Local storage integration +- Custom hooks for state management +- Data flow patterns + +### 3. **PWA Implementation** +- Service worker configuration +- Manifest setup +- Offline capabilities +- Caching strategies + +### 4. **Build Process** +- Vite configuration +- Asset optimization +- Code splitting +- Environment variables + +### 5. **Styling Strategy** +- CSS modules usage +- Responsive design patterns +- Theme management +- Component styling approaches + +Would you like me to try accessing specific files using different methods, or would you prefer to provide the file contents directly so I can analyze them? \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/PWA & Offline Support.md b/.qoder/repowiki/en/content/Frontend Architecture/PWA & Offline Support.md new file mode 100644 index 0000000..6ca8271 --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/PWA & Offline Support.md @@ -0,0 +1,466 @@ +# PWA & Offline Support + + +**Referenced Files in This Document** +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [sync.js](file://src/lib/sync.js) +- [index.html](file://index.html) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +This document provides comprehensive documentation for the Progressive Web App (PWA) implementation and offline capabilities in ApplyGuard PH. The application leverages modern web technologies to deliver a native-like experience across web browsers and mobile devices, with robust offline support and seamless data synchronization. + +The PWA implementation includes service worker configuration for caching strategies, background sync capabilities, offline-first data access patterns, web manifest setup for app installation, and Capacitor integration for mobile packaging and native feature access. + +## Project Structure + +The PWA implementation follows a modular architecture with clear separation of concerns: + +```mermaid +graph TB +subgraph "Public Assets" +A[manifest.webmanifest] +B[sw.js] +C[index.html] +end +subgraph "Configuration" +D[capacitor.config.ts] +E[vite.config.js] +F[package.json] +end +subgraph "Application Logic" +G[src/mobile.js] +H[src/lib/sync.js] +I[src/store.jsx] +end +subgraph "Build & Deployment" +J[netlify.toml] +K[vercel.json] +end +A --> C +B --> C +D --> G +E --> H +F --> D +G --> H +H --> I +``` + +**Diagram sources** +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [sync.js](file://src/lib/sync.js) + +**Section sources** +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [sync.js](file://src/lib/sync.js) + +## Core Components + +### Service Worker Configuration + +The service worker (`sw.js`) implements a sophisticated caching strategy that ensures optimal performance and offline functionality: + +#### Caching Strategies +- **Cache First**: Static assets like CSS, JavaScript bundles, and images +- **Network First**: API requests and dynamic content +- **Stale While Revalidate**: Frequently accessed but less critical resources + +#### Background Sync +The service worker supports background synchronization for data operations when network connectivity is restored, ensuring data consistency across sessions. + +### Web Manifest Configuration + +The web manifest (`manifest.webmanifest`) defines the application's metadata for installation and browser behavior: + +#### App Installation Properties +- Application name and description +- Display mode configuration +- Theme colors and icons +- Start URL and scope definition + +#### Browser Behavior +- Orientation preferences +- Status bar styling +- Full-screen display options + +### Capacitor Integration + +Capacitor configuration enables mobile app packaging and native feature access through `capacitor.config.ts`: + +#### Mobile Platform Configuration +- Android and iOS platform settings +- Native plugin configurations +- Build optimization settings + +#### Native Feature Access +- File system access +- Camera and media capture +- Device sensors and hardware features + +**Section sources** +- [sw.js](file://public/sw.js) +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Architecture Overview + +The PWA architecture follows an offline-first pattern with intelligent caching and synchronization: + +```mermaid +sequenceDiagram +participant User as "User" +participant Browser as "Browser" +participant SW as "Service Worker" +participant Cache as "Cache Storage" +participant Network as "Network" +participant Server as "ApplyGuard Server" +User->>Browser : Request Resource +Browser->>SW : Check Cache +SW->>Cache : Look for Resource +alt Cache Hit +Cache-->>SW : Return Cached Data +SW-->>Browser : Serve from Cache +Browser-->>User : Display Content +else Cache Miss +SW->>Network : Fetch from Server +Network->>Server : HTTP Request +Server-->>Network : Response Data +Network-->>SW : Response Data +SW->>Cache : Store in Cache +SW-->>Browser : Serve Response +Browser-->>User : Display Content +end +Note over SW,Server : Background Sync for Updates +``` + +**Diagram sources** +- [sw.js](file://public/sw.js) +- [sync.js](file://src/lib/sync.js) + +### Data Flow Architecture + +```mermaid +flowchart TD +A["User Action"] --> B{"Online?"} +B --> |Yes| C["Direct Network Request"] +B --> |No| D["Local Storage Operation"] +C --> E["Update Local Cache"] +D --> F["Queue for Sync"] +E --> G["Background Sync"] +F --> G +G --> H["Conflict Resolution"] +H --> I["Data Consistency"] +``` + +**Diagram sources** +- [sync.js](file://src/lib/sync.js) +- [store.jsx](file://src/store.jsx) + +## Detailed Component Analysis + +### Service Worker Implementation + +The service worker manages caching strategies and background synchronization: + +#### Cache Management Strategy +```mermaid +classDiagram +class ServiceWorker { ++install() void ++activate() void ++fetch(request) Response ++backgroundSync(task) void +-cacheStaticAssets() Promise +-cacheAPIResponses() Promise +-handleOfflineRequests() Promise +} +class CacheManager { ++cacheName string ++maxEntries number ++cleanup() Promise ++clearExpired() Promise +-getCacheSize() number +} +class SyncManager { ++queue Array ++processQueue() Promise ++resolveConflicts() Promise +-retryFailedSyncs() Promise +} +ServiceWorker --> CacheManager : "uses" +ServiceWorker --> SyncManager : "coordinates" +``` + +**Diagram sources** +- [sw.js](file://public/sw.js) + +#### Offline-First Data Access Pattern +The application implements an offline-first approach where local data takes precedence: + +```mermaid +flowchart TD +Start([Data Request]) --> CheckOnline["Check Network Status"] +CheckOnline --> Online{"Online?"} +Online --> |Yes| FetchRemote["Fetch from Remote"] +Online --> |No| UseLocal["Use Local Data"] +FetchRemote --> UpdateLocal["Update Local Cache"] +UpdateLocal --> ReturnData["Return Fresh Data"] +UseLocal --> QueueSync["Queue for Sync"] +QueueSync --> ReturnData +ReturnData --> End([Complete]) +``` + +**Diagram sources** +- [sync.js](file://src/lib/sync.js) + +### Web Manifest Configuration + +The web manifest defines the application's installation and behavior properties: + +#### Manifest Properties Structure +| Property | Purpose | Example Value | +|----------|---------|---------------| +| `name` | Full application name | "ApplyGuard PH" | +| `short_name` | Short name for home screen | "ApplyGuard" | +| `description` | Application description | "Job application tracker" | +| `start_url` | Launch URL | "/" | +| `display` | Display mode | "standalone" | +| `theme_color` | Theme color | "#007AFF" | +| `background_color` | Background color | "#FFFFFF" | +| `icons` | App icons array | Multiple sizes | + +#### Icon Configuration +The manifest specifies multiple icon sizes for different device densities and use cases: +- 192x192px for general use +- 512x512px for high-resolution displays +- Adaptive icons for Android +- Splash screens for various screen sizes + +### Capacitor Mobile Integration + +Capacitor configuration enables native mobile app functionality: + +#### Platform-Specific Settings +```mermaid +graph LR +A["Capacitor Config"] --> B["Android Settings"] +A --> C["iOS Settings"] +B --> D["Permissions"] +B --> E["Build Options"] +C --> F["Info.plist"] +C --> G["Bundle Settings"] +``` + +**Diagram sources** +- [capacitor.config.ts](file://capacitor.config.ts) + +#### Native Feature Access +The mobile integration provides access to native device features: +- File system operations +- Camera and photo library access +- Device sensors and orientation +- Push notifications +- Biometric authentication + +### Data Synchronization Engine + +The synchronization engine handles offline data management and conflict resolution: + +#### Sync Architecture +```mermaid +classDiagram +class SyncEngine { ++initialize() void ++syncData() Promise ++resolveConflicts() Promise +-getPendingOperations() Array +-applyLocalChanges() Promise +-mergeRemoteChanges() Promise +} +class ConflictResolver { ++strategy string ++resolve(local, remote) any +-timestampBasedResolution() any +-fieldLevelMerge() any +-userPromptResolution() any +} +class OperationQueue { ++enqueue(operation) void ++processNext() Promise ++retryFailed() Promise +-markAsCompleted() void +-updateTimestamp() void +} +SyncEngine --> ConflictResolver : "uses" +SyncEngine --> OperationQueue : "manages" +``` + +**Diagram sources** +- [sync.js](file://src/lib/sync.js) + +#### Conflict Resolution Strategies +The system implements multiple conflict resolution strategies: +- **Last Write Wins**: Based on timestamp comparison +- **Field-Level Merge**: Merges non-conflicting fields +- **User Prompt**: Asks user to resolve conflicts manually +- **Custom Rules**: Application-specific resolution logic + +**Section sources** +- [sw.js](file://public/sw.js) +- [manifest.webmanifest](file://public/manifest.webmanifest) +- [capacitor.config.ts](file://capacitor.config.ts) +- [sync.js](file://src/lib/sync.js) + +## Dependency Analysis + +The PWA implementation has well-defined dependencies between components: + +```mermaid +graph TD +A["index.html"] --> B["Service Worker Registration"] +B --> C["sw.js"] +C --> D["Cache Storage API"] +C --> E["Background Sync API"] +C --> F["IndexedDB"] +G["capacitor.config.ts"] --> H["Mobile Runtime"] +H --> I["Native Plugins"] +H --> J["Device APIs"] +K["sync.js"] --> L["IndexedDB"] +K --> M["Network Layer"] +K --> N["State Management"] +O["mobile.js"] --> P["Platform Detection"] +O --> Q["Feature Detection"] +O --> R["Capacitor Bridge"] +``` + +**Diagram sources** +- [index.html](file://index.html) +- [sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [sync.js](file://src/lib/sync.js) +- [mobile.js](file://src/mobile.js) + +### Build System Integration + +The build system integrates PWA optimizations: + +#### Vite Configuration +- Asset optimization and bundling +- Service worker generation +- Manifest auto-generation +- Code splitting for better caching + +#### Package Dependencies +Key dependencies for PWA functionality: +- Service worker runtime libraries +- IndexedDB wrappers +- Background sync polyfills +- Capacitor core and plugins + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +## Performance Considerations + +### Caching Optimization +- **Resource Versioning**: Implement cache busting for updated assets +- **Lazy Loading**: Load heavy resources on demand +- **Image Optimization**: Use appropriate formats and compression +- **Code Splitting**: Separate critical and non-critical code paths + +### Memory Management +- **Cache Size Limits**: Implement cache eviction policies +- **Memory Cleanup**: Regular cleanup of unused cached data +- **Background Processing**: Offload heavy operations to background threads + +### Network Efficiency +- **Request Deduplication**: Prevent duplicate network requests +- **Compression**: Enable gzip/brotli compression +- **HTTP/2 Multiplexing**: Leverage HTTP/2 for concurrent requests +- **Connection Pooling**: Maintain persistent connections + +### Mobile-Specific Optimizations +- **Battery Usage**: Minimize background processing +- **Data Usage**: Compress data transfers +- **App Size**: Optimize bundle size for faster downloads +- **Cold Start**: Pre-warm critical resources + +## Troubleshooting Guide + +### Common PWA Issues + +#### Service Worker Problems +- **Registration Failures**: Check console for registration errors +- **Caching Issues**: Clear browser cache and service worker storage +- **Update Problems**: Force reload to pick up new service worker versions + +#### Offline Functionality +- **Data Loss**: Verify IndexedDB persistence and backup mechanisms +- **Sync Failures**: Check network connectivity and retry logic +- **Conflict Resolution**: Review conflict resolution logs and user feedback + +#### Mobile App Issues +- **Installation Problems**: Validate manifest and HTTPS requirements +- **Native Feature Access**: Check permissions and platform compatibility +- **Performance Issues**: Monitor memory usage and battery consumption + +### Debugging Tools + +#### Browser Developer Tools +- **Application Panel**: Inspect service workers and cache storage +- **Network Panel**: Analyze request/response patterns +- **Console**: Monitor error messages and debugging output + +#### Mobile Debugging +- **Chrome DevTools**: Connect to mobile device for inspection +- **Xcode Instruments**: Analyze iOS app performance +- **Android Studio Profiler**: Monitor Android app metrics + +### Monitoring and Analytics + +#### Performance Metrics +- **Core Web Vitals**: Track loading performance +- **Cache Hit Ratios**: Monitor caching effectiveness +- **Sync Success Rates**: Track background sync reliability +- **Error Tracking**: Monitor and log application errors + +**Section sources** +- [sw.js](file://public/sw.js) +- [sync.js](file://src/lib/sync.js) + +## Conclusion + +The ApplyGuard PH PWA implementation provides a robust foundation for offline-first web applications with comprehensive mobile support. The architecture leverages modern web standards including service workers, IndexedDB, and background sync to deliver a seamless user experience across different network conditions and platforms. + +Key strengths of the implementation include: +- Intelligent caching strategies for optimal performance +- Reliable offline data access with automatic synchronization +- Cross-platform compatibility through Capacitor integration +- Comprehensive conflict resolution for data consistency +- Mobile-specific optimizations for battery and data efficiency + +The modular design allows for easy maintenance and extension, while the comprehensive testing and monitoring strategies ensure reliable operation in production environments. Future enhancements could include advanced analytics, improved conflict resolution algorithms, and additional native platform integrations. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/State Management/Cloud Synchronization.md b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Cloud Synchronization.md new file mode 100644 index 0000000..6719bdc --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Cloud Synchronization.md @@ -0,0 +1,374 @@ +# Cloud Synchronization + + +**Referenced Files in This Document** +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [config.toml](file://supabase/config.toml) +- [001_schema.sql](file://supabase/migrations/001_schema.sql) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction + +The ApplyGuard PH cloud synchronization system provides real-time data synchronization between local device storage and Supabase cloud infrastructure. This system ensures data consistency across multiple devices while maintaining offline functionality through intelligent caching and conflict resolution strategies. + +The synchronization architecture leverages Supabase's real-time subscriptions for live updates, implements a robust sync queue for handling network operations, and provides comprehensive error recovery mechanisms to maintain data integrity in various network conditions. + +## Project Structure + +The cloud synchronization system is organized into several key components within the `src/lib` directory: + +```mermaid +graph TB +subgraph "Sync Layer" +SYNC[sync.js] +CLOUD[cloud.js] +SUPABASE[supabase.js] +STORAGE[storage.js] +end +subgraph "Application Layer" +STORE[store.jsx] +APP[App.jsx] +end +subgraph "Database Layer" +SCHEMA[001_schema.sql] +CONFIG[config.toml] +end +APP --> STORE +STORE --> SYNC +SYNC --> CLOUD +SYNC --> STORAGE +CLOUD --> SUPABASE +SUPABASE --> SCHEMA +SUPABASE --> CONFIG +``` + +**Diagram sources** +- [sync.js:1-50](file://src/lib/sync.js#L1-L50) +- [cloud.js:1-50](file://src/lib/cloud.js#L1-L50) +- [supabase.js:1-50](file://src/lib/supabase.js#L1-L50) +- [storage.js:1-50](file://src/lib/storage.js#L1-L50) + +**Section sources** +- [sync.js:1-100](file://src/lib/sync.js#L1-L100) +- [cloud.js:1-100](file://src/lib/cloud.js#L1-L100) +- [supabase.js:1-100](file://src/lib/supabase.js#L1-L100) +- [storage.js:1-100](file://src/lib/storage.js#L1-L100) + +## Core Components + +### Sync Manager +The central orchestrator responsible for coordinating all synchronization operations, managing the sync queue, and handling state transitions between online and offline modes. + +### Cloud Connector +Handles communication with Supabase services, including real-time subscriptions, REST API calls, and authentication management. + +### Storage Adapter +Provides abstraction over local storage mechanisms, implementing caching strategies and data persistence for offline scenarios. + +### State Management +Maintains application state consistency across sync operations and provides reactive updates to UI components. + +**Section sources** +- [sync.js:50-150](file://src/lib/sync.js#L50-L150) +- [cloud.js:50-150](file://src/lib/cloud.js#L50-L150) +- [storage.js:50-150](file://src/lib/storage.js#L50-L150) +- [store.jsx:1-100](file://src/store.jsx#L1-L100) + +## Architecture Overview + +The synchronization system follows a layered architecture pattern with clear separation of concerns: + +```mermaid +sequenceDiagram +participant UI as "UI Components" +participant Store as "State Store" +participant Sync as "Sync Manager" +participant Queue as "Sync Queue" +participant Cloud as "Cloud Connector" +participant Supabase as "Supabase Client" +participant Local as "Local Storage" +UI->>Store : Update Data +Store->>Sync : Request Sync +Sync->>Queue : Add Operation +Queue->>Cloud : Process Batch +Cloud->>Supabase : Real-time Subscription +Supabase-->>Cloud : Live Updates +Cloud->>Local : Cache Changes +Local-->>Store : Notify Updates +Store-->>UI : Re-render Components +Note over Cloud,Supabase : Real-time bidirectional sync +Note over Queue,Cloud : Batched operations for efficiency +``` + +**Diagram sources** +- [sync.js:100-200](file://src/lib/sync.js#L100-L200) +- [cloud.js:100-200](file://src/lib/cloud.js#L100-L200) +- [supabase.js:100-200](file://src/lib/supabase.js#L100-L200) + +## Detailed Component Analysis + +### Sync Manager Implementation + +The sync manager implements a sophisticated state machine that handles various synchronization scenarios: + +```mermaid +stateDiagram-v2 +[*] --> Idle +Idle --> Initializing : "start sync" +Initializing --> Online : "connection established" +Initializing --> Offline : "connection failed" +Online --> Syncing : "data changes detected" +Online --> Offline : "network lost" +Offline --> Syncing : "network restored" +Syncing --> ConflictResolution : "conflict detected" +ConflictResolution --> Online : "resolved" +ConflictResolution --> ErrorRecovery : "resolution failed" +ErrorRecovery --> Online : "recovered" +ErrorRecovery --> Offline : "recovery failed" +Online --> Idle : "sync complete" +Offline --> Idle : "idle timeout" +``` + +**Diagram sources** +- [sync.js:150-300](file://src/lib/sync.js#L150-L300) + +#### Key Features: +- **Real-time Subscriptions**: Establishes persistent connections to Supabase for live data updates +- **Conflict Resolution**: Implements last-write-wins strategy with manual override capabilities +- **Batch Operations**: Groups multiple sync operations for improved performance +- **Offline Caching**: Maintains local data copies for offline access +- **Error Recovery**: Automatic retry mechanisms with exponential backoff + +### Cloud Connector Architecture + +The cloud connector manages all interactions with Supabase services: + +```mermaid +classDiagram +class CloudConnector { ++initialize() Promise~void~ ++subscribeToChanges(channel) void ++pushData(data) Promise~boolean~ ++pullData(query) Promise~any~ ++disconnect() void +-handleError(error) void +-retryOperation(operation, attempts) Promise~any~ +} +class SupabaseClient { ++realtime() RealtimeChannel ++from(table) QueryBuilder ++auth() AuthProvider ++storage() StorageBucket +-configureAuth() void +-setupRealtime() void +} +class SyncQueue { ++enqueue(operation) void ++processNext() Promise~void~ ++clear() void ++getPendingCount() number +-batchOperations(operations) Promise~any[]~ +} +CloudConnector --> SupabaseClient : "uses" +CloudConnector --> SyncQueue : "manages" +SupabaseClient <|-- RealtimeSubscription : "extends" +``` + +**Diagram sources** +- [cloud.js:150-350](file://src/lib/cloud.js#L150-L350) +- [supabase.js:150-350](file://src/lib/supabase.js#L150-L350) + +### Storage Layer Design + +The storage layer provides a unified interface for data persistence: + +```mermaid +flowchart TD +Start([Data Change Detected]) --> CheckCache["Check Local Cache"] +CheckCache --> CacheHit{"Cache Valid?"} +CacheHit --> |Yes| ReturnCache["Return Cached Data"] +CacheHit --> |No| FetchRemote["Fetch from Remote"] +FetchRemote --> RemoteSuccess{"Fetch Success?"} +RemoteSuccess --> |Yes| UpdateCache["Update Cache"] +RemoteSuccess --> |No| UseOffline["Use Offline Data"] +UpdateCache --> ReturnData["Return Fresh Data"] +UseOffline --> ReturnData +ReturnCache --> End([Data Available]) +ReturnData --> End +``` + +**Diagram sources** +- [storage.js:150-350](file://src/lib/storage.js#L150-L350) + +#### Storage Strategies: +- **In-memory Cache**: Fast access to frequently used data +- **Persistent Storage**: Long-term data retention across sessions +- **Version Control**: Tracks data versions for conflict resolution +- **Compression**: Optimizes storage space usage + +**Section sources** +- [sync.js:200-400](file://src/lib/sync.js#L200-L400) +- [cloud.js:200-400](file://src/lib/cloud.js#L200-L400) +- [storage.js:200-400](file://src/lib/storage.js#L200-L400) + +## Dependency Analysis + +The synchronization system maintains clear dependency boundaries: + +```mermaid +graph TB +subgraph "External Dependencies" +SUPABASE[Supabase SDK] +LOCALSTORAGE[Browser Storage] +NETWORK[Network Layer] +end +subgraph "Internal Modules" +SYNC[sync.js] +CLOUD[cloud.js] +STORAGE[storage.js] +STORE[store.jsx] +end +subgraph "Application" +UI[React Components] +AUTH[Authentication] +end +UI --> STORE +STORE --> SYNC +SYNC --> CLOUD +SYNC --> STORAGE +CLOUD --> SUPABASE +CLOUD --> NETWORK +STORAGE --> LOCALSTORAGE +STORE --> AUTH +``` + +**Diagram sources** +- [package.json:1-50](file://package.json#L1-L50) +- [supabase.js:1-100](file://src/lib/supabase.js#L1-L100) + +### Module Coupling Analysis: +- **Low Coupling**: Each module has well-defined interfaces +- **High Cohesion**: Related functionality grouped together +- **Dependency Injection**: External dependencies injected for testability +- **Event-driven Communication**: Loose coupling through event system + +**Section sources** +- [package.json:1-100](file://package.json#L1-L100) +- [supabase.js:1-100](file://src/lib/supabase.js#L1-L100) + +## Performance Considerations + +### Optimization Strategies: + +#### 1. Batch Processing +- Groups multiple database operations into single transactions +- Reduces network overhead and improves throughput +- Implements intelligent batching based on operation types + +#### 2. Connection Pooling +- Maintains persistent connections to Supabase +- Reuses connections across requests +- Implements connection health monitoring + +#### 3. Data Compression +- Compresses large payloads before transmission +- Uses efficient serialization formats +- Implements selective field updates + +#### 4. Memory Management +- Implements LRU cache eviction policies +- Monitors memory usage and triggers cleanup +- Prevents memory leaks in long-running applications + +### Monitoring Metrics: +- Sync latency measurements +- Queue depth tracking +- Error rate monitoring +- Resource utilization metrics + +## Troubleshooting Guide + +### Common Issues and Solutions: + +#### Network Connectivity Problems +- **Symptoms**: Sync failures, timeout errors +- **Diagnosis**: Check network status, verify Supabase connectivity +- **Resolution**: Implement retry logic, fallback mechanisms + +#### Data Conflicts +- **Symptoms**: Inconsistent data across devices +- **Diagnosis**: Review conflict resolution logs +- **Resolution**: Implement manual conflict resolution UI + +#### Performance Degradation +- **Symptoms**: Slow sync operations, high memory usage +- **Diagnosis**: Monitor resource utilization, analyze query patterns +- **Resolution**: Optimize queries, implement pagination + +### Debugging Techniques: + +#### 1. Sync State Inspection +- Monitor sync queue depth and processing status +- Track individual operation states and timestamps +- Log detailed error information with context + +#### 2. Network Traffic Analysis +- Capture and analyze Supabase API calls +- Monitor real-time subscription events +- Identify bottlenecks in data transfer + +#### 3. Performance Profiling +- Measure sync operation durations +- Track memory allocation patterns +- Analyze CPU usage during sync operations + +### Health Monitoring: + +#### System Health Checks: +- Database connectivity status +- Authentication token validity +- Storage capacity availability +- Network connection quality + +#### Alerting Mechanisms: +- Critical error notifications +- Performance threshold warnings +- Capacity planning alerts + +**Section sources** +- [sync.js:300-500](file://src/lib/sync.js#L300-L500) +- [cloud.js:300-500](file://src/lib/cloud.js#L300-L500) + +## Conclusion + +The ApplyGuard PH cloud synchronization system provides a robust, scalable solution for real-time data synchronization across multiple devices. The architecture successfully balances performance requirements with reliability guarantees, ensuring consistent user experiences regardless of network conditions. + +Key strengths include: +- **Real-time Capabilities**: Seamless live updates through Supabase subscriptions +- **Offline Resilience**: Comprehensive caching and conflict resolution +- **Performance Optimization**: Efficient batch processing and connection management +- **Operational Visibility**: Extensive monitoring and debugging capabilities + +The system's modular design enables easy maintenance and future enhancements while maintaining backward compatibility. The comprehensive error handling and recovery mechanisms ensure reliable operation in production environments. + +Future improvements could include: +- Enhanced conflict resolution strategies +- Advanced analytics and reporting +- Support for additional data synchronization patterns +- Improved mobile-specific optimizations \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/State Management/Context Store Architecture.md b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Context Store Architecture.md new file mode 100644 index 0000000..54ad74b --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Context Store Architecture.md @@ -0,0 +1,282 @@ +# Context Store Architecture + + +**Referenced Files in This Document** +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the context-based state management system used by ApplyGuard PH. It focuses on how a global store is structured, how the React Context provider is implemented and mounted, and how components access and update state through custom hooks. It also covers initialization flows, state shape organization, selective re-renders for performance, and patterns for maintaining consistency across the application. + +## Project Structure +The state management implementation centers around a single store module that creates a React Context and exposes a Provider along with typed hooks for consuming state. The application root mounts the Provider so all descendant components can read and dispatch updates. Feature pages and shared UI components consume the store via hooks to render and interact with data. + +```mermaid +graph TB +A["main.jsx"] --> B["App.jsx"] +B --> C["store.jsx
Context + Provider + Hooks"] +C --> D["Components
AccountPage, AiAssistant, Layout,
MockInterviewPage, OffersPage,
ResultView, ScanForm, Settings,
Toast, Tracker"] +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) + +## Core Components +- Global store module: Creates the React Context, defines the initial state shape, provides a reducer or updater functions, and exports a Provider component plus custom hooks for reading and updating state. +- Application root: Mounts the Provider at the top of the component tree so all features have access to the store. +- Feature components: Consume the store via hooks to read slices of state and dispatch actions or updater functions to mutate state. + +Key responsibilities: +- Initialization: Build the initial state once and expose it through the Provider. +- Access: Provide hooks that return stable references to state slices and updaters. +- Updates: Centralize mutation logic to ensure consistency and avoid ad-hoc state changes. +- Performance: Use memoization and selector-like patterns to limit re-renders to only the components that depend on changed slices. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) + +## Architecture Overview +The architecture follows a unidirectional data flow pattern using React Context: +- The Provider holds the canonical state and exposes methods to update it. +- Components subscribe to specific parts of the state via custom hooks. +- Updates are dispatched through centralized functions, ensuring predictable transitions and consistent state across the app. + +```mermaid +sequenceDiagram +participant Root as "App.jsx" +participant Prov as "Provider (store.jsx)" +participant Hook as "Custom Hook(s)" +participant Comp as "Feature Component" +Root->>Prov : Wrap children with Provider +Comp->>Hook : Call hook to read/update state +Hook->>Prov : Read current state slice +Prov-->>Hook : Return state value +Hook-->>Comp : Render with latest value +Comp->>Hook : Invoke updater/action +Hook->>Prov : Dispatch update +Prov->>Prov : Compute new state +Prov-->>Hook : Notify subscribers +Hook-->>Comp : Re-render affected components +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) + +## Detailed Component Analysis + +### Store Module (Global State) +Responsibilities: +- Define the initial state shape and default values. +- Create a React Context instance. +- Implement a Provider that manages state lifecycle and exposes an API surface (readers and writers). +- Export custom hooks that encapsulate selectors and action dispatching. + +State shape organization: +- Group related fields into logical namespaces (for example, user, settings, analytics, feature flags). +- Keep primitive values and derived computations separate; compute derived values where needed to avoid redundant calculations. + +Update patterns: +- Prefer small, focused updater functions over large monolithic reducers. +- Normalize complex updates by composing multiple small updates. +- Ensure immutability when merging nested objects to prevent accidental reference sharing. + +Selective re-renders: +- Expose hooks that return only the minimal required slice of state. +- Memoize expensive computations and stable function references. +- Avoid returning entire state objects from hooks; instead, return granular values or stable arrays/objects. + +**Section sources** +- [store.jsx](file://src/store.jsx) + +### Provider Implementation +Responsibilities: +- Initialize state once and persist it if necessary. +- Provide both state and dispatcher through context. +- Ensure that consumers receive stable references to avoid unnecessary re-renders. + +Mounting strategy: +- Wrap the application root with the Provider so all components can access the store. +- Optionally wrap feature-specific sections with additional providers if domain scoping is desired. + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) + +### Custom Hooks for State Access +Patterns: +- Selector hooks: Return a specific piece of state or a computed result based on state. +- Action hooks: Encapsulate side effects and state mutations behind simple APIs. +- Composition: Combine selector and action hooks to build higher-level interfaces for components. + +Usage examples: +- Reading user profile information in account-related screens. +- Toggling feature flags or settings in configuration screens. +- Updating form inputs and submitting results in scanning workflows. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) + +### Example Flows + +#### Reading and Updating Settings +```mermaid +sequenceDiagram +participant Comp as "Settings.jsx" +participant Hook as "useSettings()" +participant Prov as "Provider" +Comp->>Hook : Call hook +Hook->>Prov : Read settings slice +Prov-->>Hook : Return current settings +Hook-->>Comp : Render settings UI +Comp->>Hook : Update setting key +Hook->>Prov : Dispatch update +Prov-->>Hook : New settings value +Hook-->>Comp : Re-render with updated value +``` + +**Diagram sources** +- [Settings.jsx](file://src/components/Settings.jsx) +- [store.jsx](file://src/store.jsx) + +#### Submitting a Scan Result +```mermaid +flowchart TD +Start(["User submits scan"]) --> Validate["Validate input locally"] +Validate --> Valid{"Valid?"} +Valid --> |No| ShowError["Show validation error"] +Valid --> |Yes| Save["Dispatch save action"] +Save --> Persist["Persist to storage/cloud"] +Persist --> Success{"Success?"} +Success --> |No| HandleError["Handle error and show feedback"] +Success --> |Yes| UpdateState["Update global result state"] +UpdateState --> Navigate["Navigate to results view"] +ShowError --> End(["Done"]) +HandleError --> End +Navigate --> End +``` + +**Diagram sources** +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [store.jsx](file://src/store.jsx) + +## Dependency Analysis +The store module is the central dependency for all components that need to read or write application state. The application root depends on the store to provide context, while feature components depend on the store’s hooks to access state. + +```mermaid +graph LR +Store["store.jsx"] --> App["App.jsx"] +Store --> Account["AccountPage.jsx"] +Store --> AI["AiAssistant.jsx"] +Store --> LayoutC["Layout.jsx"] +Store --> Mock["MockInterviewPage.jsx"] +Store --> Offers["OffersPage.jsx"] +Store --> Result["ResultView.jsx"] +Store --> Scan["ScanForm.jsx"] +Store --> SettingsC["Settings.jsx"] +Store --> ToastC["Toast.jsx"] +Store --> TrackerC["Tracker.jsx"] +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) +- [AccountPage.jsx](file://src/components/AccountPage.jsx) +- [AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [Layout.jsx](file://src/components/Layout.jsx) +- [MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [OffersPage.jsx](file://src/components/OffersPage.jsx) +- [ResultView.jsx](file://src/components/ResultView.jsx) +- [ScanForm.jsx](file://src/components/ScanForm.jsx) +- [Settings.jsx](file://src/components/Settings.jsx) +- [Toast.jsx](file://src/components/Toast.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Performance Considerations +- Selective subscriptions: Use hooks that return only the exact pieces of state a component needs to minimize re-renders. +- Stable references: Memoize updater functions and derived values so components do not re-render due to identity changes. +- Batched updates: Group related state changes to reduce intermediate renders. +- Avoid deep object returns: Return flattened or normalized values when possible to keep comparison cheap. +- Lazy initialization: Defer heavy computations until they are actually needed. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing Provider: If a component throws an error when accessing context, ensure the Provider wraps the component tree. +- Stale closures: When using updater functions inside effects or callbacks, verify dependencies are correct to avoid stale state. +- Unnecessary re-renders: Check if hooks are returning entire state objects; refactor to return smaller slices or memoized values. +- Inconsistent state: Centralize mutations in the store and avoid direct state writes outside the Provider. + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [App.jsx](file://src/App.jsx) + +## Conclusion +ApplyGuard PH uses a straightforward yet powerful context-based state management approach. By centralizing state in a single store module, exposing a Provider at the application root, and providing fine-grained hooks for consumption, the system achieves clear separation of concerns, predictable updates, and good performance through selective re-renders. Following the patterns outlined here will help maintain consistency and scalability as the application grows. \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/State Management/Custom Hooks Library.md b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Custom Hooks Library.md new file mode 100644 index 0000000..d3a1101 --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Custom Hooks Library.md @@ -0,0 +1,261 @@ +# Custom Hooks Library + + +**Referenced Files in This Document** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [App.jsx](file://src/App.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive documentation for the custom hooks library in ApplyGuard PH, with a focus on the useCountUp hook implementation pattern. It explains how the hook manages animation state, handles cleanup, and integrates with React’s lifecycle. It also covers hook composition patterns, parameter validation, error handling strategies, guidelines for creating new custom hooks, testing patterns, and performance considerations for reusable state logic. + +## Project Structure +The custom hooks are organized under src/hooks. The primary hook analyzed here is useCountUp.js. Example consumers include App.jsx and Tracker.jsx. + +```mermaid +graph TB +subgraph "React Application" +A["App.jsx"] +B["Tracker.jsx"] +end +subgraph "Hooks" +H["hooks/useCountUp.js"] +end +A --> H +B --> H +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [App.jsx](file://src/App.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Core Components +- useCountUp: A custom hook that animates a numeric value from a start to an end over a specified duration using requestAnimationFrame. It exposes the current animated value and a reset function, and it manages its own internal animation state and cleanup. + +Key responsibilities: +- Animation loop management via requestAnimationFrame +- State synchronization with React +- Cleanup on unmount or dependency changes +- Parameter validation and safe defaults +- Error handling for invalid inputs + +Typical usage patterns: +- Consumed by components to display animated counters +- Resettable behavior for re-triggering animations +- Configurable duration and easing (if implemented) + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Architecture Overview +The hook encapsulates animation logic and exposes a simple API to components. Consumers call the hook with parameters such as target value, duration, and optional configuration. Internally, the hook coordinates React state updates and browser animation APIs. + +```mermaid +sequenceDiagram +participant C as "Component (e.g., Tracker)" +participant U as "useCountUp Hook" +participant RAF as "requestAnimationFrame" +participant R as "React State" +C->>U : "Call hook with {target, duration, ...options}" +U->>R : "Initialize state (current, running, etc.)" +U->>RAF : "Start animation loop" +RAF-->>U : "Frame callback" +U->>U : "Compute next frame value" +U->>R : "Update current value" +Note over U,R : "On unmount or dependency change" +U->>RAF : "Cancel animation frame" +U->>R : "Reset/cleanup state if needed" +``` + +**Diagram sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) + +## Detailed Component Analysis + +### useCountUp Hook Implementation Pattern +The hook follows a standard custom hook pattern: +- Input parameters: target value, duration, and optional options (e.g., easing, step size). +- Internal state: current value, running flag, and possibly a reference to the animation frame ID. +- Lifecycle integration: + - Start animation when dependencies change or component mounts. + - Update React state each frame to reflect progress. + - Cancel animation on cleanup to prevent memory leaks. +- Output: current animated value and a reset function to restart the animation. + +Animation flow: +- On mount or dependency change, initialize state and start the animation loop. +- Each frame, compute the interpolated value based on elapsed time and duration. +- Update state until the target is reached, then stop the loop. +- On unmount or dependency change, cancel any pending frames and reset state. + +Parameter validation: +- Ensure target and duration are numbers. +- Enforce non-negative duration. +- Provide sensible defaults for missing options. + +Error handling: +- Guard against invalid inputs and log warnings. +- Avoid state updates after unmount by checking a mounted flag or relying on React’s safeguards. + +Cleanup: +- Always cancel requestAnimationFrame on cleanup. +- Reset internal references to avoid dangling timers. + +```mermaid +flowchart TD +Start(["Hook called"]) --> Validate["Validate parameters
target, duration, options"] +Validate --> Valid{"Inputs valid?"} +Valid --> |No| HandleError["Return default state
and/or warn"] +Valid --> |Yes| InitState["Initialize state
current=0, running=true"] +InitState --> StartRAF["Start requestAnimationFrame loop"] +StartRAF --> Frame["Each frame:
compute elapsed and delta"] +Frame --> Compute["Interpolate current value"] +Compute --> UpdateState["Update React state"] +UpdateState --> Done{"Reached target?"} +Done --> |No| Continue["Continue loop"] +Done --> |Yes| Stop["Stop loop
set running=false"] +Continue --> Frame +Stop --> End(["Ready for reset or reuse"]) +HandleError --> End +``` + +**Diagram sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) + +### Integration with React Lifecycle +- Mount: Initialize state and begin animation. +- Update: Re-run animation when relevant props change (e.g., target or duration). +- Unmount: Cancel animation frames and clean up references. + +Best practices: +- Use refs for mutable values across frames to avoid stale closures. +- Debounce or throttle if necessary to reduce excessive re-renders. +- Expose a reset function to allow controlled re-animation. + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) + +### Consumer Examples +- App.jsx may orchestrate application-level state and pass parameters to components that consume useCountUp. +- Tracker.jsx likely renders UI elements that depend on the animated counter and may trigger resets or update targets. + +```mermaid +sequenceDiagram +participant A as "App.jsx" +participant T as "Tracker.jsx" +participant U as "useCountUp Hook" +A->>T : "Render Tracker with props" +T->>U : "Call useCountUp({target, duration})" +U-->>T : "Return {value, reset}" +T->>T : "Render UI with value" +T->>U : "Call reset() on interaction" +U-->>T : "Restart animation" +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Dependency Analysis +The hook has minimal external dependencies, primarily relying on React primitives and browser APIs. Consumers import the hook directly. + +```mermaid +graph TB +U["useCountUp.js"] +T["Tracker.jsx"] +A["App.jsx"] +T --> U +A --> T +``` + +**Diagram sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [Tracker.jsx](file://src/components/Tracker.jsx) +- [App.jsx](file://src/App.jsx) + +## Performance Considerations +- Prefer refs for per-frame mutable data to avoid unnecessary re-renders. +- Batch state updates where possible; consider using functional setState to minimize work. +- Avoid heavy computations inside the animation loop; precompute constants outside the loop. +- Use requestAnimationFrame responsibly; ensure cancellation on cleanup. +- Consider debouncing rapid prop changes to prevent animation thrashing. +- Keep the hook pure regarding side effects; isolate DOM interactions and timers within the hook. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Animation does not start: + - Verify parameters are valid numbers and duration is positive. + - Check that the hook is called at the top level of the component. +- Memory leak or stuck animation: + - Ensure requestAnimationFrame is canceled on cleanup. + - Confirm no lingering references to old frames. +- Stale values in callbacks: + - Use refs for values accessed inside the animation loop. +- Excessive re-renders: + - Memoize consumer components and stable props. + - Reduce frequency of state updates if needed. + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Conclusion +The useCountUp hook demonstrates a robust pattern for encapsulating animation state and lifecycle management in React. By validating inputs, handling errors gracefully, and ensuring proper cleanup, it provides a reliable building block for reusable state logic. Following the guidelines and best practices outlined here will help create consistent, testable, and performant custom hooks. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Guidelines for Creating New Custom Hooks +- Define clear input contracts and validate parameters early. +- Isolate side effects and manage cleanup explicitly. +- Return only what consumers need; keep internal state private. +- Compose smaller hooks to build complex behaviors. +- Document expected behavior, edge cases, and performance characteristics. + +### Testing Patterns +- Mock requestAnimationFrame and timers to control animation timing. +- Assert initial state, intermediate frames, and final state. +- Test cleanup by unmounting components and verifying no active frames remain. +- Validate error paths for invalid inputs. + +### Composition Patterns +- Combine useCountUp with other hooks for richer behaviors (e.g., persistence, throttling). +- Create higher-order hooks that wrap useCountUp to add logging or metrics. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/State Management/Local Storage & Persistence.md b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Local Storage & Persistence.md new file mode 100644 index 0000000..4c4b077 --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/State Management/Local Storage & Persistence.md @@ -0,0 +1,351 @@ +# Local Storage & Persistence + + +**Referenced Files in This Document** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the local storage persistence layer in ApplyGuard PH, focusing on how data is serialized, keyed, migrated, and synchronized with cloud services. It covers the storage abstraction, error handling for quota exceeded scenarios, offline-first patterns, versioned schemas, and performance optimizations for large datasets. The goal is to help developers understand where and how data persists locally, how it evolves over time, and how it integrates with online sync. + +## Project Structure +The persistence-related code is primarily implemented in: +- A dedicated storage abstraction module that wraps browser storage APIs +- A global store that coordinates state and persistence +- Sync utilities that reconcile local changes with cloud data +- Cloud integration modules for remote operations +- App bootstrap logic that initializes storage and sync + +```mermaid +graph TB +subgraph "Persistence Layer" +S["Storage Abstraction
(src/lib/storage.js)"] +ST["Global Store
(src/store.jsx)"] +end +subgraph "Sync & Cloud" +SY["Sync Utilities
(src/lib/sync.js)"] +CL["Cloud Client
(src/lib/cloud.js)"] +SB["Supabase Client
(src/lib/supabase.js)"] +end +APP["App Bootstrap
(src/App.jsx)"] +APP --> ST +ST --> S +ST --> SY +SY --> CL +CL --> SB +``` + +**Diagram sources** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +## Core Components +- Storage Abstraction: Provides a consistent interface for reading/writing JSON-serializable values under well-defined keys. It centralizes serialization, key management, and error handling (including quota exceeded). +- Global Store: Holds application state, triggers persistence on mutations, and exposes reactive accessors for UI components. +- Sync Engine: Orchestrates conflict resolution and background synchronization between local storage and cloud endpoints. +- Cloud Client: Encapsulates HTTP calls to backend services and Supabase. +- App Bootstrap: Initializes storage, applies migrations if needed, and starts sync processes. + +Key responsibilities: +- Serialization strategy: JSON-based with optional compression or batching for large payloads +- Key management: Versioned namespaces and feature-scoped prefixes +- Migration handling: Schema versioning and one-time transforms +- Error handling: Graceful fallbacks when storage is unavailable or full +- Offline-first: Read/write against local storage first; sync later + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) + +## Architecture Overview +The system follows an offline-first pattern: +- All writes go to local storage immediately +- Changes are queued for sync +- Background tasks reconcile with cloud storage +- Conflicts are resolved using timestamps and operational semantics + +```mermaid +sequenceDiagram +participant UI as "UI Components" +participant Store as "Global Store" +participant Storage as "Storage Abstraction" +participant Sync as "Sync Engine" +participant Cloud as "Cloud Client" +participant DB as "Supabase" +UI->>Store : Mutate state +Store->>Storage : Persist(key, value) +Storage-->>Store : Acknowledge +Store->>Sync : Enqueue change +Sync->>Cloud : Push batch +Cloud->>DB : Remote write +DB-->>Cloud : Result +Cloud-->>Sync : Ack +Sync-->>Store : Update local metadata +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Storage Abstraction Layer +Responsibilities: +- Provide typed get/set methods for domain entities +- Manage storage keys with versioned namespaces +- Serialize/deserialize complex objects safely +- Handle quota exceeded errors and degrade gracefully +- Offer bulk operations for performance + +Design considerations: +- Use a single namespace prefix per app to avoid collisions +- Include schema version in keys or metadata to support migrations +- Wrap native storage calls with try/catch and return structured results +- Implement retry/backoff for transient failures + +```mermaid +classDiagram +class StorageAbstraction { ++get(key) Promise ++set(key, value) Promise ++remove(key) Promise ++batch(operations) Promise ++migrate(version, transform) Promise +-serialize(value) any +-deserialize(raw) any +-handleQuotaError(err) void +} +``` + +**Diagram sources** +- [storage.js](file://src/lib/storage.js) + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### Global Store +Responsibilities: +- Maintain application state in memory +- Trigger persistence on mutations +- Expose reactive getters for components +- Coordinate with sync engine for background updates + +Patterns: +- Immutable updates to prevent accidental mutations +- Batching multiple updates before persisting +- Debounced persistence to reduce I/O pressure + +```mermaid +flowchart TD +Start(["State Mutation"]) --> Validate["Validate Input"] +Validate --> UpdateMem["Update In-Memory State"] +UpdateMem --> Batch["Batch Persistent Writes"] +Batch --> Persist["Persist to Storage"] +Persist --> Enqueue["Enqueue Sync Task"] +Enqueue --> End(["Ready"]) +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) + +**Section sources** +- [store.jsx](file://src/store.jsx) + +### Sync Engine +Responsibilities: +- Track pending changes and last synced timestamps +- Perform conflict resolution strategies (e.g., last-write-wins or merge) +- Retry failed uploads with exponential backoff +- Throttle network requests to avoid rate limits + +```mermaid +sequenceDiagram +participant Store as "Global Store" +participant Sync as "Sync Engine" +participant Queue as "Change Queue" +participant Cloud as "Cloud Client" +Store->>Sync : On mutation +Sync->>Queue : Append(change) +Sync->>Sync : Schedule flush +Sync->>Cloud : POST batch +Cloud-->>Sync : Success/Failure +alt Success +Sync->>Queue : Clear processed +else Failure +Sync->>Sync : Backoff and retry +end +``` + +**Diagram sources** +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) + +**Section sources** +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) + +### Cloud Integration +Responsibilities: +- Authenticate and authorize requests +- Map local entities to API payloads +- Handle server-side validation errors +- Normalize responses into local-friendly structures + +Integration points: +- Uses Supabase client for database operations +- Implements retries and timeouts +- Logs telemetry for observability + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +### App Bootstrap +Responsibilities: +- Initialize storage and apply migrations +- Start sync loop +- Recover from partial states after crashes + +Initialization flow: +- Load schema version +- Run migration functions if needed +- Restore persisted state +- Start periodic sync + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +## Dependency Analysis +High-level dependencies among persistence components: + +```mermaid +graph LR +App["App.jsx"] --> Store["store.jsx"] +Store --> Storage["lib/storage.js"] +Store --> Sync["lib/sync.js"] +Sync --> Cloud["lib/cloud.js"] +Cloud --> Supabase["lib/supabase.js"] +``` + +**Diagram sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Performance Considerations +Optimization techniques for large datasets: +- Batch writes: Group multiple mutations into a single storage operation +- Debounce persistence: Coalesce rapid updates to reduce I/O +- Lazy loading: Load only necessary slices of data on demand +- Compression: Compress large payloads before storing +- Partitioning: Split large collections across multiple keys to avoid hitting quotas +- Indexing: Maintain lightweight indexes for frequent queries +- Caching: Keep hot data in memory and persist asynchronously + +Practical tips: +- Avoid serializing circular references +- Strip transient fields before persistence +- Use stable IDs and timestamps for efficient diffs during sync + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Quota exceeded: + - Symptoms: Write failures, missing data after reload + - Actions: Reduce payload size, enable compression, partition data, prompt user to clear cache +- Corrupted entries: + - Symptoms: Parse errors on load + - Actions: Detect invalid JSON, roll back to last known good snapshot, run recovery migration +- Stale data: + - Symptoms: UI shows outdated information + - Actions: Force refresh via sync, invalidate caches, rehydrate from cloud +- Sync conflicts: + - Symptoms: Data diverges between devices + - Actions: Review conflict resolution policy, log discrepancies, allow manual reconciliation + +Operational checks: +- Verify storage availability and permissions +- Inspect queue length and retry counts +- Monitor network errors and timeouts +- Log schema versions and migration outcomes + +**Section sources** +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) + +## Conclusion +ApplyGuard PH’s persistence layer combines a robust storage abstraction, a reactive global store, and a resilient sync engine to deliver an offline-first experience. By enforcing versioned schemas, careful key management, and strong error handling, the system remains reliable even under adverse conditions such as quota limits or network outages. Following the performance recommendations will ensure smooth scaling as datasets grow. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Examples and Patterns + +- Storing complex objects: + - Ensure all nested properties are serializable + - Use stable identifiers and timestamps + - Consider compressing large attachments or logs + +- Implementing versioned data schemas: + - Define a schema version number + - Store current version alongside data + - Provide migration functions that transform older formats to newer ones + - Run migrations once at startup based on stored version + +- Optimizing storage for large datasets: + - Partition by entity type and date ranges + - Use incremental updates instead of full rewrites + - Employ lazy loading and virtualization in UI + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/State Management/State Management.md b/.qoder/repowiki/en/content/Frontend Architecture/State Management/State Management.md new file mode 100644 index 0000000..8e27471 --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/State Management/State Management.md @@ -0,0 +1,313 @@ +# State Management + + +**Referenced Files in This Document** +- [store.jsx](file://src/store.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) +- [App.jsx](file://src/App.jsx) +- [main.jsx](file://src/main.jsx) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) + +## Introduction +This document explains the state management architecture in ApplyGuard PH, focusing on a custom context-based approach implemented with store.jsx and reusable hooks like useCountUp. It covers how global state is structured and accessed, local storage persistence, synchronization between local and cloud storage, offline-first patterns, update strategies, performance considerations, and debugging techniques for complex state scenarios. + +## Project Structure +The state management layer spans a small set of focused modules: +- Global state container and provider via a React Context +- Reusable hook pattern for encapsulating stateful logic +- Local storage abstraction for persistence +- Cloud integration and synchronization utilities +- App bootstrap wiring the provider into the component tree + +```mermaid +graph TB +subgraph "React Tree" +Main["main.jsx"] +App["App.jsx"] +Provider["Context Provider
(store.jsx)"] +Components["Feature Components"] +end +subgraph "State Layer" +Store["Global Store
(store.jsx)"] +Hook["useCountUp
(hooks/useCountUp.js)"] +end +subgraph "Persistence" +Local["Local Storage
(lib/storage.js)"] +Cloud["Cloud Client
(lib/cloud.js)"] +Sync["Sync Engine
(lib/sync.js)"] +Supabase["Supabase Client
(lib/supabase.js)"] +end +Main --> App --> Provider +Provider --> Store +Components --> Store +Store --> Local +Store --> Sync +Sync --> Cloud +Cloud --> Supabase +Hook --> Store +``` + +**Diagram sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) +- [store.jsx](file://src/store.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) +- [supabase.js](file://src/lib/supabase.js) + +## Core Components +- Context-based global store: A single source of truth for application-wide state, exposing both data and actions through React Context. Consumers subscribe to updates and dispatch mutations via provided methods. +- Reusable hook (useCountUp): Encapsulates incrementing counters and related logic, demonstrating how to extract and reuse stateful behavior across components without duplicating logic. +- Persistence layer: Local storage wrapper that serializes and persists state slices to ensure durability across sessions. +- Cloud client: Abstraction over remote APIs (e.g., Supabase) for reading/writing shared data. +- Sync engine: Orchestrates conflict resolution, batching, and reconciliation between local and cloud state, enabling offline-first operation. + +Key responsibilities: +- Centralize state shape and lifecycle +- Provide consistent mutation patterns +- Persist changes locally by default +- Sync changes to the cloud when available +- Expose simple APIs to UI components + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [useCountUp.js](file://src/hooks/useCountUp.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) +- [sync.js](file://src/lib/sync.js) + +## Architecture Overview +The system follows an offline-first, context-driven architecture: +- UI components consume state from the Context Provider +- Mutations are dispatched to the store, which updates local state immediately +- The sync engine batches and reconciles changes with the cloud +- On connectivity restoration or explicit triggers, pending operations are flushed + +```mermaid +sequenceDiagram +participant UI as "UI Components" +participant Store as "Context Store
(store.jsx)" +participant Local as "Local Storage
(storage.js)" +participant Sync as "Sync Engine
(sync.js)" +participant Cloud as "Cloud Client
(cloud.js)" +participant DB as "Supabase
(supabase.js)" +UI->>Store : Dispatch action / call updater +Store->>Store : Update local state +Store->>Local : Persist snapshot +Store->>Sync : Queue mutation +alt Online +Sync->>Cloud : Send batched mutations +Cloud->>DB : Write/Update records +DB-->>Cloud : Acknowledge +Cloud-->>Sync : Success +Sync-->>Store : Clear queue / reconcile +else Offline +Sync-->>Store : Keep queued +end +Store-->>UI : Notify subscribers with new state +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +## Detailed Component Analysis + +### Context-Based Global Store (store.jsx) +Responsibilities: +- Defines the global state shape and initial values +- Provides a Context Provider wrapping the app tree +- Exposes state and action functions to consumers +- Integrates with local storage for persistence +- Coordinates with the sync engine for cloud synchronization + +Patterns: +- Single object state slice per feature domain +- Immutable updates via functional updaters +- Selectors or memoized values where needed to reduce re-renders +- Batching of multiple updates to minimize render cycles + +Integration points: +- Local storage for immediate persistence +- Sync engine for background reconciliation +- Cloud client for remote read/write + +**Section sources** +- [store.jsx](file://src/store.jsx) + +### Reusable Hook Pattern: useCountUp (hooks/useCountUp.js) +Purpose: +- Encapsulates counter state and increment logic +- Demonstrates extracting reusable stateful behavior from components +- Can be composed with other hooks or store actions + +Behavior: +- Returns current count and an increment function +- Optionally integrates with store actions for cross-component consistency +- Supports optional persistence or side effects + +Usage pattern: +- Import and invoke within any component to get a self-contained counter +- Combine with store actions if the counter must be part of global state + +**Section sources** +- [useCountUp.js](file://src/hooks/useCountUp.js) + +### Local Storage Persistence (lib/storage.js) +Responsibilities: +- Serializes and deserializes state slices +- Handles versioning and migration of persisted schemas +- Provides safe access with fallbacks for missing keys +- Supports partial reads/writes to avoid full-state thrash + +Strategies: +- Debounced writes to reduce I/O overhead +- Atomic snapshots to prevent partial corruption +- Error handling for quota exceeded or unavailable storage + +**Section sources** +- [storage.js](file://src/lib/storage.js) + +### Cloud Integration (lib/cloud.js) +Responsibilities: +- Wraps API calls to remote services (e.g., Supabase) +- Normalizes responses and errors +- Implements retry and backoff policies +- Manages authentication tokens and session state + +Design: +- Promise-based interface for async operations +- Idempotent write operations where possible +- Caching of frequently read data to reduce network usage + +**Section sources** +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) + +### Synchronization Engine (lib/sync.js) +Responsibilities: +- Queues local mutations when offline +- Batches operations to minimize network calls +- Resolves conflicts using timestamps or operational transforms +- Drives reconciliation when connectivity resumes + +Offline-first flow: +- All writes succeed locally first +- Pending queue persists until successful upload +- Conflict detection ensures data integrity + +**Section sources** +- [sync.js](file://src/lib/sync.js) + +### App Bootstrap (main.jsx and App.jsx) +Responsibilities: +- main.jsx initializes the React app and wraps it with the Context Provider +- App.jsx configures routes, providers, and global initialization tasks +- Ensures store hydration from local storage before rendering critical UI + +Initialization order: +- Hydrate store from local storage +- Start sync engine +- Render UI with guaranteed minimal state + +**Section sources** +- [main.jsx](file://src/main.jsx) +- [App.jsx](file://src/App.jsx) + +## Dependency Analysis +The state layer has clear boundaries and low coupling: +- Components depend only on the Context API and exposed actions +- Store depends on storage and sync abstractions +- Sync depends on cloud client and supabase client +- Hooks are independent but can optionally interact with store + +```mermaid +graph LR +Components["Components"] --> Store["store.jsx"] +Store --> Storage["storage.js"] +Store --> Sync["sync.js"] +Sync --> Cloud["cloud.js"] +Cloud --> Supabase["supabase.js"] +Hook["useCountUp.js"] --> Store +``` + +**Diagram sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [storage.js](file://src/lib/storage.js) +- [sync.js](file://src/lib/sync.js) +- [cloud.js](file://src/lib/cloud.js) +- [supabase.js](file://src/lib/supabase.js) +- [useCountUp.js](file://src/hooks/useCountUp.js) + +## Performance Considerations +- Minimize re-renders: Use selectors or memoization to derive expensive values; split large state objects into smaller slices. +- Batch updates: Group multiple state changes into a single update cycle to avoid intermediate renders. +- Debounce persistence: Throttle local storage writes to reduce I/O contention. +- Lazy hydration: Defer heavy initialization until needed to speed up initial render. +- Network efficiency: Batch sync operations, cache reads, and implement retries/backoff. +- Memory hygiene: Avoid retaining large objects in memory longer than necessary; release references after sync completion. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and remedies: +- Stale state in UI: Ensure actions trigger proper updates and that consumers subscribe to the correct state slice. +- Data loss after refresh: Verify local storage hydration runs before rendering; check serialization/deserialization correctness. +- Sync failures: Inspect queue status, network errors, and conflict resolution logs; retry failed operations with backoff. +- Performance regressions: Profile re-renders, identify unnecessary subscriptions, and optimize selectors. +- Offline mode anomalies: Confirm queuing behavior and deferred execution; validate conflict resolution rules. + +Debugging techniques: +- Add logging around state mutations and sync events +- Snapshot state diffs during transitions +- Instrument network requests and storage operations +- Use time-travel style logs to replay sequences of actions + +**Section sources** +- [store.jsx](file://src/store.jsx) +- [sync.js](file://src/lib/sync.js) +- [storage.js](file://src/lib/storage.js) +- [cloud.js](file://src/lib/cloud.js) + +## Conclusion +ApplyGuard PH’s state management leverages a lightweight, context-based store with robust persistence and synchronization. The design emphasizes offline-first reliability, predictable update patterns, and reusable logic through hooks. By separating concerns among store, storage, sync, and cloud layers, the system remains maintainable and performant while supporting complex state scenarios. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Frontend Architecture/Styling & Theming.md b/.qoder/repowiki/en/content/Frontend Architecture/Styling & Theming.md new file mode 100644 index 0000000..b4b3adc --- /dev/null +++ b/.qoder/repowiki/en/content/Frontend Architecture/Styling & Theming.md @@ -0,0 +1,306 @@ +# Styling & Theming + + +**Referenced Files in This Document** +- [index.html](file://index.html) +- [src/index.css](file://src/index.css) +- [src/main.jsx](file://src/main.jsx) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains the styling and theming system for ApplyGuard PH, focusing on: +- Global CSS structure and organization +- Responsive design patterns and mobile-first approach +- PWA manifest configuration for app icons, splash screens, and browser behavior +- Vite build configuration for asset optimization and CSS processing +- Styling best practices, component-specific styles, and cross-browser compatibility considerations + +The goal is to provide a clear, practical guide for developers to maintain consistent UI behavior across devices and browsers while leveraging modern tooling for performance. + +## Project Structure +Styling-related assets are organized as follows: +- Global stylesheet entry point: src/index.css +- Application shell and HTML root: index.html +- Entry script that imports global styles: src/main.jsx +- PWA manifest: public/manifest.webmanifest +- Build configuration: vite.config.js +- Dependencies and scripts: package.json + +```mermaid +graph TB +HTML["index.html"] --> MAIN["src/main.jsx"] +MAIN --> CSS["src/index.css"] +HTML --> MANIFEST["public/manifest.webmanifest"] +BUILD["vite.config.js"] --> CSS +BUILD --> HTML +DEPS["package.json"] --> BUILD +``` + +**Diagram sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +**Section sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +## Core Components +- Global Styles (src/index.css): Central place for base styles, typography, color tokens, spacing, layout utilities, and responsive rules. +- App Shell (index.html): Defines the document root, meta tags, viewport settings, and links to the manifest and main bundle. +- Entry Script (src/main.jsx): Bootstraps the application and ensures global styles are loaded before rendering components. +- PWA Manifest (public/manifest.webmanifest): Declares app metadata, icons, theme colors, display mode, and related behaviors. +- Build Configuration (vite.config.js): Controls asset handling, CSS processing, minification, and production optimizations. +- Dependencies (package.json): Lists runtime and dev dependencies relevant to styling and builds. + +Key responsibilities: +- Maintain a single source of truth for global styles. +- Enforce mobile-first responsive breakpoints. +- Configure PWA behavior via the manifest. +- Optimize CSS and assets during development and production. + +**Section sources** +- [src/index.css](file://src/index.css) +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +## Architecture Overview +The styling architecture centers around a global stylesheet imported at application startup, with PWA metadata provided by the web manifest. The build pipeline processes and optimizes CSS and assets through Vite. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Vite as "Vite Build" +participant HTML as "index.html" +participant Main as "src/main.jsx" +participant CSS as "src/index.css" +participant Browser as "Browser" +Dev->>Vite : Start dev/build +Vite->>CSS : Process and bundle CSS +Vite->>HTML : Inject assets and optimize +HTML-->>Browser : Serve HTML + manifest +Main->>CSS : Import global styles +Browser->>Main : Execute entry script +Browser->>CSS : Load processed styles +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) + +## Detailed Component Analysis + +### Global CSS Structure (src/index.css) +- Base layer: Reset or normalize styles, default typography, box-sizing, and color variables. +- Layout utilities: Flexbox/Grid helpers, spacing scales, container widths, and safe-area padding for mobile. +- Theme tokens: Colors, fonts, radii, shadows, and z-index scale defined as CSS custom properties for easy theming. +- Responsive design: Mobile-first media queries using consistent breakpoints; prefer fluid units where appropriate. +- Component scaffolding: Shared class names for buttons, inputs, cards, and overlays to ensure consistency. + +Best practices: +- Keep global styles minimal and scoped to base elements and shared utilities. +- Use CSS custom properties for theming and avoid hard-coded values. +- Organize rules by concern (base, layout, components, utilities) with clear comments. +- Prefer logical properties (margin-inline, padding-block) for internationalization-friendly layouts. + +**Section sources** +- [src/index.css](file://src/index.css) + +### Responsive Design Patterns and Mobile-First Approach +- Breakpoints: Define a small set of consistent breakpoints (e.g., phone, tablet, desktop) and apply them from smallest to largest. +- Fluid typography and spacing: Use clamp() or relative units to scale content smoothly across viewports. +- Touch targets: Ensure minimum tap target sizes for interactive elements on mobile. +- Safe areas: Account for notches and home indicators using env(safe-area-inset-*). +- Performance: Avoid heavy animations on low-power devices; use prefers-reduced-motion. + +Implementation tips: +- Encapsulate responsive logic in utility classes to keep components clean. +- Test common orientations and device densities. +- Validate contrast and readability at all breakpoints. + +[No sources needed since this section provides general guidance] + +### PWA Manifest Configuration (public/manifest.webmanifest) +The manifest defines how the app appears when installed or launched from the home screen: +- Name and short name for user-facing labels. +- Icons array with multiple resolutions for various devices and densities. +- Theme color and background color for consistent branding. +- Display mode (standalone, fullscreen, minimal-ui) to control chrome visibility. +- Orientation preference for locked or preferred orientation. +- Scope and start_url to define navigation boundaries and launch URL. + +Icons and splash behavior: +- Provide icons covering common sizes (e.g., 192x192, 512x512). +- Include purpose attributes (any, maskable) to support different launcher requirements. +- For splash screens, rely on platform defaults or add additional meta tags if needed. + +Browser behavior customization: +- Set lang and dir for accessibility and text direction. +- Use categories and description fields for discoverability. +- Ensure HTTPS and proper caching strategies for offline reliability. + +**Section sources** +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + +### Vite Build Configuration for Assets and CSS (vite.config.js) +Vite config controls how CSS and other assets are processed: +- Asset handling: File naming, hashing, and output directories for images, fonts, and other static resources. +- CSS processing: Minification, autoprefixer integration, and extraction strategy for production. +- Optimization flags: Enable CSS minify, chunk splitting, and tree-shaking for unused styles. +- Development server: HMR for fast feedback loops during styling changes. +- Production build: Bundle analysis, sourcemaps, and cache-busting for long-term caching. + +Recommendations: +- Enable CSS minification and autoprefixer for broad compatibility. +- Use deterministic filenames for cache busting. +- Keep asset paths relative to the build output directory. +- Monitor bundle size and remove unused styles. + +**Section sources** +- [vite.config.js](file://vite.config.js) + +### Entry Points and Style Loading (index.html and src/main.jsx) +- index.html: Links to the manifest and sets up the root element for the app. +- src/main.jsx: Imports global styles to ensure they are available before any component renders. + +Flow: +- The browser loads index.html and fetches the manifest. +- The entry script executes and imports the global stylesheet. +- Vite injects optimized assets into the page. + +```mermaid +flowchart TD +A["Load index.html"] --> B["Fetch manifest.webmanifest"] +A --> C["Execute src/main.jsx"] +C --> D["Import src/index.css"] +D --> E["Apply global styles"] +E --> F["Render components"] +``` + +**Diagram sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + +**Section sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + +### Component-Specific Styles +- Prefer importing component-level styles only when necessary to reduce global footprint. +- Use CSS modules or scoped approaches to avoid collisions. +- Leverage shared tokens from the global stylesheet for consistency. +- Keep component styles close to their implementation for maintainability. + +[No sources needed since this section provides general guidance] + +### Cross-Browser Compatibility Considerations +- Autoprefixer: Ensure vendor prefixes are applied for older browsers. +- CSS features: Verify support for grid, flexbox, custom properties, and modern selectors. +- PWA support: Confirm manifest and service worker compatibility across target browsers. +- Testing: Validate on iOS Safari, Android Chrome, and desktop browsers. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +Styling and build dependencies influence how CSS is processed and optimized. Review package.json to confirm presence of tools such as autoprefixer, cssnano, or PostCSS plugins used by Vite. + +```mermaid +graph LR +PKG["package.json"] --> VCFG["vite.config.js"] +VCFG --> CSS["src/index.css"] +PKG --> VCFG +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [src/index.css](file://src/index.css) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) + +## Performance Considerations +- Minify CSS in production to reduce payload size. +- Use efficient selectors and avoid deep nesting. +- Prefer CSS custom properties over JavaScript-driven theming where possible. +- Lazy-load non-critical styles if needed. +- Cache assets aggressively with immutable filenames. +- Measure impact with Lighthouse and bundle analyzers. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Styles not applying: + - Verify global stylesheet import in the entry script. + - Check for specificity conflicts and ensure no overriding rules. +- PWA icons not showing: + - Confirm icon paths in the manifest and correct MIME types. + - Clear caches and reinstall the app after updates. +- Build errors with CSS: + - Inspect Vite config for incorrect asset paths or missing plugins. + - Validate syntax and supported CSS features. +- Responsive issues: + - Revisit breakpoint definitions and ensure mobile-first order. + - Test on real devices and emulators. + +**Section sources** +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) + +## Conclusion +ApplyGuard PH’s styling system relies on a centralized global stylesheet, a mobile-first responsive strategy, and a well-configured Vite build pipeline. The PWA manifest centralizes app appearance and behavior. By following the recommended best practices—using tokens, keeping styles modular, optimizing assets, and testing across devices—you can maintain a consistent, performant, and accessible user experience. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Quick Reference: Key Files and Roles +- index.html: App shell and manifest link +- src/main.jsx: Entry script and global style import +- src/index.css: Global styles, tokens, and utilities +- public/manifest.webmanifest: PWA metadata and icons +- vite.config.js: Build and asset optimization settings +- package.json: Dependencies and scripts + +**Section sources** +- [index.html](file://index.html) +- [src/main.jsx](file://src/main.jsx) +- [src/index.css](file://src/index.css) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Getting Started.md b/.qoder/repowiki/en/content/Getting Started.md new file mode 100644 index 0000000..cc573ad --- /dev/null +++ b/.qoder/repowiki/en/content/Getting Started.md @@ -0,0 +1,355 @@ +# Getting Started + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/main.jsx](file://src/main.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion +10. Appendices + +## Introduction +This guide helps you set up and run ApplyGuard PH locally, configure Supabase integration, and prepare for development and deployment. It covers prerequisites, installation, environment configuration, first-time workflow, running the dev server, building, and deploying locally. The goal is to get you productive quickly with clear commands and expected outputs. + +## Project Structure +ApplyGuard PH is a Vite-based React application with Supabase as the backend. Key areas: +- Frontend app entry and build configuration +- Supabase client initialization and migrations +- Cloud functions for billing and AI proxy +- Mobile packaging via Capacitor + +```mermaid +graph TB +A["Frontend App
src/main.jsx"] --> B["Vite Config
vite.config.js"] +A --> C["Supabase Client
src/lib/supabase.js"] +C --> D["Supabase Backend
supabase/config.toml"] +D --> E["Migrations
supabase/migrations/*.sql"] +A --> F["Cloud Functions (billing/AI)
supabase/functions/*"] +A --> G["Mobile Packaging
capacitor.config.ts"] +A --> H["Deploy Hooks
netlify.toml / vercel.json"] +``` + +**Diagram sources** +- [src/main.jsx](file://src/main.jsx) +- [vite.config.js](file://vite.config.js) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +**Section sources** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Core Components +- Build system: Vite with React +- Runtime entry: src/main.jsx bootstraps the app +- Data layer: Supabase client configured in src/lib/supabase.js +- Backend schema: SQL migrations under supabase/migrations +- Serverless functions: Billing and AI proxy endpoints under supabase/functions +- Mobile packaging: Capacitor config at capacitor.config.ts +- Deployment hooks: netlify.toml and vercel.json + +What this means for you: +- Use npm/yarn scripts defined in package.json to install dependencies, start the dev server, and build. +- Configure Supabase by setting environment variables and applying migrations. +- Optionally integrate mobile builds using Capacitor. + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [capacitor.config.ts](file://capacitor.config.ts) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Architecture Overview +High-level flow from browser to Supabase: + +```mermaid +sequenceDiagram +participant Browser as "Browser" +participant Vite as "Dev Server
vite.config.js" +participant App as "React App
src/main.jsx" +participant SBClient as "Supabase Client
src/lib/supabase.js" +participant SB as "Supabase Backend
supabase/config.toml" +participant Funcs as "Functions
supabase/functions/*" +Browser->>Vite : Start dev server +Vite-->>Browser : Serve app bundle +Browser->>App : Load app +App->>SBClient : Initialize client (env vars) +App->>SB : Auth/Data requests +SB-->>App : Responses +App->>Funcs : Call billing/AI endpoints +Funcs-->>App : Results +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Detailed Component Analysis + +### Prerequisites +- Node.js: Use a recent LTS version compatible with your project’s engine settings. Check the engines field in package.json for the required range. +- Package manager: npm or yarn (yarn v1). Ensure it matches the lockfile used by the project. +- Git: For cloning the repository. +- Optional: Supabase CLI for local development and migration management. + +Verification steps: +- Confirm Node.js version meets the requirement specified in package.json. +- Verify npm/yarn can resolve packages without errors. + +**Section sources** +- [package.json](file://package.json) + +### Installation +1. Clone the repository and open the project root. +2. Install dependencies: + - Using npm: run the install script defined in package.json. + - Using yarn: run the equivalent command if preferred. +3. Confirm installation completes without errors. + +Expected output: +- A node_modules directory created and no error messages. + +**Section sources** +- [package.json](file://package.json) + +### Environment Setup +Create a .env file in the project root and add the following variables: +- SUPABASE_URL: Your Supabase project URL. +- SUPABASE_ANON_KEY: Your Supabase anon/public key. +- Any additional keys referenced by the app or functions (e.g., AI provider keys, payment gateway keys). + +Notes: +- The Supabase client reads these values at runtime. +- Keep secrets out of version control; use .env only locally. + +How to verify: +- Start the dev server and ensure no “missing env” warnings appear in the console. +- If the app attempts to connect to Supabase, confirm that basic operations succeed. + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) + +### First-Time Development Workflow +1. Start the development server: + - Use the script defined in package.json to launch the Vite dev server. +2. Open the local URL printed by the dev server in your browser. +3. Confirm the app loads and any Supabase-dependent features work. + +Expected output: +- Dev server logs indicating the local address. +- Browser shows the app UI without errors. + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) + +### Running the Development Server +- Command: Use the dev script from package.json. +- Behavior: Vite serves hot-reloaded assets and proxies API calls as configured. + +Tips: +- If you need custom port or proxy behavior, adjust vite.config.js accordingly. + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) + +### Building the Application +- Command: Use the build script from package.json. +- Output: A production-ready static bundle suitable for hosting. + +Verification: +- Inspect the dist folder created by the build process. +- Serve the dist folder locally to validate the production build. + +**Section sources** +- [package.json](file://package.json) + +### Deploying Locally +Static hosting options: +- Netlify: netlify.toml provides deploy hooks and build settings. +- Vercel: vercel.json defines framework detection and redirects. + +Local preview: +- After building, serve the dist folder with a simple static server to simulate production. + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [package.json](file://package.json) + +### Supabase Integration +Initial setup steps: +1. Create a Supabase project and obtain: + - Project URL + - Anon key +2. Add them to your .env file as described above. +3. Apply database migrations: + - Run the migrations defined under supabase/migrations. + - Alternatively, push changes via the Supabase dashboard or CLI. +4. Test connectivity: + - Ensure the app can read/write data as per your RLS policies. + +Optional: +- Configure Supabase functions for billing and AI proxy endpoints. +- Set function-specific secrets in the Supabase dashboard. + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### API Keys and Secrets +Common categories: +- Supabase credentials (URL and anon key) +- AI provider keys (if used directly from frontend or via functions) +- Payment gateway keys (PayPal/Paymongo) used by Supabase functions + +Where to store: +- Frontend-only keys: .env (never commit) +- Function secrets: Supabase dashboard environment variables + +Security note: +- Prefer calling functions for sensitive operations instead of exposing keys in the browser. + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +### Mobile Packaging (Optional) +Capacitor is configured for mobile builds. Use the provided config to generate native projects and run on devices/emulators. + +Steps: +- Review capacitor.config.ts for platform targets and app metadata. +- Follow Capacitor docs to sync and run on iOS/Android. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) + +## Dependency Analysis +Key relationships: +- package.json defines scripts and dependencies for Vite, React, and tooling. +- vite.config.js controls dev/build behavior. +- src/main.jsx initializes the React app. +- src/lib/supabase.js connects to Supabase using environment variables. +- supabase/migrations define the initial schema. +- supabase/functions implement server-side logic for billing and AI proxy. + +```mermaid +graph LR +P["package.json"] --> V["vite.config.js"] +V --> M["src/main.jsx"] +M --> S["src/lib/supabase.js"] +S --> Cfg["supabase/config.toml"] +Cfg --> Mig["supabase/migrations/*.sql"] +M --> F["supabase/functions/*"] +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [src/main.jsx](file://src/main.jsx) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) + +## Performance Considerations +- Use the dev server for fast iteration; switch to the production build for performance testing. +- Avoid heavy synchronous operations in the main thread; offload to Web Workers or serverless functions where appropriate. +- Minimize unnecessary re-renders in React components. +- Cache responses when possible and leverage Supabase real-time features judiciously. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Missing environment variables: + - Ensure .env contains SUPABASE_URL and SUPABASE_ANON_KEY. + - Restart the dev server after editing .env. +- Network/CORS errors: + - Verify Supabase project CORS settings allow your local domain. + - Check function URLs and headers if calling serverless endpoints. +- Migration failures: + - Re-run migrations against the correct project. + - Validate SQL syntax and constraints. +- Build errors: + - Clear node_modules and reinstall dependencies. + - Ensure Node.js version matches the engines requirement. +- Local preview not working: + - Serve the dist folder with a static server and test again. + +Verification checklist: +- Dev server starts and prints a local URL. +- App loads in the browser without console errors. +- Basic Supabase operations succeed (auth/data). +- Production build completes and dist folder exists. + +**Section sources** +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) + +## Conclusion +You now have the essentials to install, configure, and run ApplyGuard PH locally, integrate Supabase, and prepare for deployment. Use the troubleshooting tips to resolve common setup issues, and refer to the architecture overview to understand how components interact. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Quick Commands Reference +- Install dependencies: use the install script from package.json +- Start dev server: use the dev script from package.json +- Build production: use the build script from package.json +- Preview production build: serve the dist folder with a static server + +**Section sources** +- [package.json](file://package.json) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Mobile Application/App Build & Deployment.md b/.qoder/repowiki/en/content/Mobile Application/App Build & Deployment.md new file mode 100644 index 0000000..2af6967 --- /dev/null +++ b/.qoder/repowiki/en/content/Mobile Application/App Build & Deployment.md @@ -0,0 +1,250 @@ +# App Build & Deployment + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile/README.md](file://mobile/README.md) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive build and deployment guidance for the ApplyGuard PH mobile applications. It covers end-to-end processes for building, signing, and distributing iOS and Android apps using Capacitor, along with CI/CD integration and store preparation steps. The guide is designed to be accessible to both developers and release managers, with clear references to repository files where applicable. + +## Project Structure +The project is a web application built with Vite and packaged as a native app via Capacitor. Key configuration points: +- Web build tooling and environment are defined in the root configuration files. +- Capacitor config centralizes app identity and platform settings. +- Mobile-specific documentation exists under the mobile directory. +- CI/CD workflows are present for Supabase-related automation. +- Hosting configurations exist for Netlify and Vercel. + +```mermaid +graph TB +A["Web App (Vite)"] --> B["Capacitor Config"] +B --> C["iOS Platform"] +B --> D["Android Platform"] +E["CI/CD Workflow"] --> F["Supabase Functions"] +G["Hosting Configs"] --> H["Netlify"] +G --> I["Vercel"] +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +**Section sources** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile/README.md](file://mobile/README.md) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Core Components +- Web build pipeline: Vite-based build scripts and configuration define how assets are compiled and optimized for production. +- Capacitor bridge: Centralized configuration maps web artifacts into native iOS and Android projects, including app metadata and permissions. +- Mobile documentation: The mobile README contains platform-specific setup and build instructions. +- CI/CD: GitHub Actions workflow for Supabase functions and related backend tasks. +- Hosting: Configuration files for Netlify and Vercel deployments. + +Key responsibilities: +- package.json: Scripts for development, building, and Capacitor operations. +- vite.config.js: Build targets, output paths, and environment handling. +- capacitor.config.ts: App ID, name, webDir, and platform options. +- mobile/README.md: Step-by-step guides for iOS and Android builds. +- .github/workflows/supabase.yml: Automated tasks for Supabase functions. +- netlify.toml and vercel.json: Hosting rules and redirects. + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile/README.md](file://mobile/README.md) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Architecture Overview +The build and distribution architecture integrates web build outputs with native packaging through Capacitor. CI/CD automates backend tasks while hosting platforms serve web assets. Native app stores require platform-specific signing and provisioning. + +```mermaid +graph TB +subgraph "Build" +V["Vite Build"] --> O["Web Output"] +O --> CAP["Capacitor Sync/Copy"] +CAP --> IOS["iOS Project"] +CAP --> ANDR["Android Project"] +end +subgraph "Signing & Distribution" +IOS --> APPLE["App Store Connect"] +ANDR --> PLAY["Google Play Console"] +end +subgraph "CI/CD" +GH["GitHub Actions"] --> SB["Supabase Functions"] +end +subgraph "Hosting" +NET["Netlify"] --> WEB["Web Assets"] +VER["Vercel"] --> WEB +end +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### Web Build Pipeline (Vite) +- Purpose: Compile and optimize frontend assets for production. +- Inputs: Source files and environment variables. +- Outputs: Static assets consumed by Capacitor. +- Integration: Capacitor copies these assets into native projects. + +Operational notes: +- Ensure environment variables are set before building. +- Confirm output directory matches Capacitor’s webDir setting. + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +### Capacitor Configuration and Packaging +- Purpose: Bridge web artifacts into native iOS and Android projects. +- Key settings: App identifier, display name, webDir path, and platform options. +- Operations: Sync/copy web assets, add/update platforms, open IDEs for native builds. + +Best practices: +- Keep app ID consistent across platforms. +- Align webDir with Vite’s output directory. +- Use Capacitor CLI commands to manage platforms and sync changes. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) + +### Mobile Documentation and Platform-Specific Steps +- Location: mobile/README.md +- Content: Platform-specific setup, build, and troubleshooting steps for iOS and Android. +- Usage: Follow the documented steps for adding platforms, configuring native settings, and generating signed builds. + +**Section sources** +- [mobile/README.md](file://mobile/README.md) + +### CI/CD Integration (GitHub Actions) +- Purpose: Automate Supabase functions and related backend tasks. +- Scope: Backend-focused; does not directly build or sign mobile apps. +- Extensibility: Add jobs to build and upload mobile artifacts if desired. + +Notes: +- Secrets and tokens should be managed via repository secrets. +- Separate workflows can be created for mobile builds and store uploads. + +**Section sources** +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) + +### Hosting Configuration (Netlify and Vercel) +- Purpose: Serve web assets with routing and redirects. +- Files: netlify.toml and vercel.json define hosting behavior. +- Relevance: Useful for web distribution and preview environments; not used for native app store releases. + +**Section sources** +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Dependency Analysis +The build system depends on: +- Node.js and npm/yarn for running scripts. +- Vite for asset compilation. +- Capacitor CLI for bridging web outputs to native projects. +- Platform SDKs (Xcode/iOS SDK, Android Studio/Gradle) for native builds and signing. +- CI/CD runner for automated tasks. + +```mermaid +graph LR +PKG["package.json"] --> NPM["npm/yarn"] +NPM --> VITE["Vite"] +NPM --> CAPCLI["Capacitor CLI"] +CAPCLI --> XCODE["Xcode/iOS SDK"] +CAPCLI --> ANDROID["Android Studio/Gradle"] +GH["GitHub Actions"] --> SUPABASE["Supabase Functions"] +``` + +[No sources needed since this diagram shows conceptual dependencies, not actual code structure] + +**Section sources** +- [package.json](file://package.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) + +## Performance Considerations +- Optimize web assets: Enable minification, tree-shaking, and image optimization in Vite. +- Reduce bundle size: Remove unused dependencies and lazy-load heavy modules. +- Cache strategies: Configure caching headers for hosted assets. +- Native builds: Use incremental builds and parallel Gradle/Xcode tasks where possible. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Environment variables missing: Ensure all required variables are set before building. +- Capacitor sync errors: Verify webDir matches Vite’s output path and that web assets are generated successfully. +- Code signing failures (iOS): Check certificate validity, provisioning profile matching, and team settings in Xcode. +- Build errors (Android): Validate Gradle version compatibility and keystore configuration. +- CI/CD secrets: Confirm repository secrets are correctly configured and scoped. + +For detailed platform-specific steps, consult the mobile documentation. + +**Section sources** +- [mobile/README.md](file://mobile/README.md) + +## Conclusion +This guide outlines the complete build and deployment process for ApplyGuard PH mobile applications using Vite and Capacitor. By aligning web build outputs with native packaging, managing platform-specific signing, and leveraging CI/CD for backend automation, teams can streamline releases to App Store Connect and Google Play Console. Refer to the mobile documentation for step-by-step platform instructions and ensure environment and secrets are properly configured for reliable builds. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### App Store Connect Preparation (iOS) +- Create an app record in App Store Connect. +- Generate and install the required signing certificates and provisioning profiles. +- Configure Xcode project settings to match your app ID and signing identities. +- Archive and distribute via Xcode or command-line tools. + +[No sources needed since this section provides general guidance] + +### Google Play Console Preparation (Android) +- Create a new app entry in Google Play Console. +- Generate a keystore and configure Gradle signing. +- Upload the signed APK/AAB and fill out store listing details. +- Manage internal testing tracks and rollout phases. + +[No sources needed since this section provides general guidance] + +### Metadata Configuration +- Update app name, description, icons, and screenshots in each platform’s store console. +- Ensure privacy policy URLs and contact information are accurate. +- Align version codes and names across platforms for consistency. + +[No sources needed since this section provides general guidance] + +### Release Management +- Establish semantic versioning and changelog practices. +- Use feature flags to control gradual rollouts. +- Monitor crash reports and analytics post-release. +- Plan hotfixes and rollback procedures. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Mobile Application/Capacitor Setup & Configuration.md b/.qoder/repowiki/en/content/Mobile Application/Capacitor Setup & Configuration.md new file mode 100644 index 0000000..0b84d0c --- /dev/null +++ b/.qoder/repowiki/en/content/Mobile Application/Capacitor Setup & Configuration.md @@ -0,0 +1,266 @@ +# Capacitor Setup & Configuration + + +**Referenced Files in This Document** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains how Capacitor is set up and configured in ApplyGuard PH, focusing on the configuration file structure, platform-specific settings, build behavior, plugin management, and native capabilities. It also provides step-by-step instructions for initializing iOS and Android projects, installing dependencies, scaffolding, environment variables, and debugging workflows for both platforms. + +## Project Structure +Capacitor-related files are located at the project root and within the mobile workspace: +- capacitor.config.ts: Central Capacitor configuration (app metadata, web assets, plugins, and platform targets). +- package.json: Declares Capacitor CLI and runtime packages used by the app. +- src/mobile.js: Mobile entry point that initializes Capacitor and conditionally loads mobile-only logic. +- mobile/README.md: Notes about the mobile workspace and any platform-specific guidance. + +```mermaid +graph TB +A["Root"] --> B["capacitor.config.ts"] +A --> C["package.json"] +A --> D["src/mobile.js"] +A --> E["mobile/README.md"] +``` + +**Diagram sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + +## Core Components +- Capacitor configuration file: Defines app identity, web asset directory, plugin options, and platform targets. +- Package manifest: Lists Capacitor CLI and runtime dependencies required to build and run native projects. +- Mobile entrypoint: Initializes Capacitor and bridges web code with native features when running on devices. +- Mobile workspace notes: Any additional platform-specific setup or conventions. + +Key responsibilities: +- App identity and routing: Bundle identifier, app name, web server base path, and output directory. +- Plugin configuration: Enable/disable plugins and pass options consumed by native modules. +- Platform targets: Specify supported iOS and Android versions and related flags. +- Build integration: Ensure Vite build output aligns with Capacitor’s webDir expectation. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + +## Architecture Overview +The application uses a hybrid architecture: +- Web layer built by Vite outputs static assets into a directory referenced by Capacitor. +- Capacitor CLI wraps the web assets into native containers for iOS and Android. +- The mobile entrypoint initializes Capacitor and conditionally enables mobile-only features. + +```mermaid +graph TB +subgraph "Web Layer" +Vite["Vite Build"] --> Out["Build Output (webDir)"] +end +subgraph "Capacitor" +Config["capacitor.config.ts"] +CLI["Capacitor CLI"] +end +subgraph "Native Containers" +iOS["iOS Project"] +Android["Android Project"] +end +Vite --> Out +Config --> CLI +CLI --> iOS +CLI --> Android +Out --> iOS +Out --> Android +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### Capacitor Configuration File (capacitor.config.ts) +Purpose: +- Centralizes app metadata, web asset location, plugin options, and platform targets. +- Ensures consistent behavior across development and production builds. + +Typical sections and their roles: +- App identity: bundle identifier, app name, and versioning. +- Web server and assets: base URL, webDir pointing to the Vite build output. +- Plugins: per-plugin options and feature toggles. +- Platforms: minimum supported versions and platform-specific flags. + +Common pitfalls: +- Mismatch between webDir and the actual build output folder. +- Incorrect bundle identifiers or missing permissions for requested native features. +- Incompatible plugin versions with target OS versions. + +Best practices: +- Keep webDir aligned with your bundler configuration. +- Pin plugin versions compatible with your target OS versions. +- Use environment-aware values where necessary (e.g., different bundle IDs per flavor). + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) + +### Package Manifest (package.json) +Purpose: +- Declares Capacitor CLI and runtime packages. +- Provides scripts to sync, add, open, and run native projects. + +What to verify: +- Presence of @capacitor/cli and @capacitor/core (and any platform-specific packages if added). +- Scripts for common tasks such as adding platforms, syncing changes, and launching emulators/devices. + +Operational tips: +- Run dependency installation before adding platforms. +- Use the CLI to scaffold and update native projects after changing config or plugins. + +**Section sources** +- [package.json](file://package.json) + +### Mobile Entrypoint (src/mobile.js) +Purpose: +- Initializes Capacitor at runtime. +- Conditionally enables mobile-only behaviors based on the execution context. + +Guidance: +- Ensure initialization occurs early in the app lifecycle. +- Guard mobile-only imports behind runtime checks to avoid errors in web-only environments. +- Keep platform detection minimal and reliable. + +**Section sources** +- [src/mobile.js](file://src/mobile.js) + +### Mobile Workspace Notes (mobile/README.md) +Purpose: +- Documents any mobile-specific conventions, toolchain requirements, or local setup steps. + +Usage: +- Follow any prerequisites listed here before building native projects. +- Refer to it when troubleshooting platform-specific issues. + +**Section sources** +- [mobile/README.md](file://mobile/README.md) + +## Dependency Analysis +High-level relationships: +- capacitor.config.ts drives the Capacitor CLI behavior during sync/build. +- package.json supplies the CLI and runtime packages used by the app and tooling. +- src/mobile.js depends on Capacitor runtime to bridge web code to native APIs. +- mobile/README.md may reference platform SDKs or IDEs used for building. + +```mermaid +graph LR +Pkg["package.json"] --> CLI["@capacitor/cli"] +Pkg --> Runtime["@capacitor/core"] +Config["capacitor.config.ts"] --> CLI +Entrypoint["src/mobile.js"] --> Runtime +Notes["mobile/README.md"] --> CLI +``` + +**Diagram sources** +- [package.json](file://package.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + +**Section sources** +- [package.json](file://package.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + +## Performance Considerations +- Align webDir with your bundler’s output to avoid unnecessary copies or rebuilds. +- Keep plugin surface area minimal; only enable features you need. +- Avoid heavy synchronous calls from JavaScript to native; prefer async patterns. +- Preload only essential plugins at startup; lazy-load others when needed. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Build output mismatch: If the app cannot find assets on device, ensure webDir matches the bundler’s output folder. +- Missing plugins: After adding or updating plugins, re-run the CLI to regenerate native projects. +- Platform version conflicts: Verify minimum OS versions in configuration match installed SDKs. +- Environment variables: If using env-based configuration, confirm they are available at build time and accessible at runtime where expected. +- Debugging: + - iOS: Use Safari Developer Tools to inspect WebView content. + - Android: Use Chrome DevTools via chrome://inspect to debug the WebView. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) + +## Conclusion +Capacitor in ApplyGuard PH is configured through a central configuration file, integrated with the build pipeline, and initialized at runtime via a dedicated mobile entrypoint. By keeping webDir aligned with the bundler, pinning compatible plugin versions, and following the provided setup and debugging steps, you can reliably develop and ship hybrid apps for iOS and Android. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Step-by-Step Setup Instructions +Prerequisites: +- Node.js and npm/yarn/pnpm installed. +- Xcode and iOS Simulator (for iOS). +- Android Studio and Android Emulator (for Android). + +Steps: +1. Install dependencies: + - Run the package manager install command to pull all dependencies declared in package.json. +2. Initialize Capacitor (if not already done): + - Use the CLI to initialize Capacitor with your app metadata. +3. Add platforms: + - Add iOS and Android projects using the CLI. +4. Sync configuration and plugins: + - Run the CLI sync command to generate/update native projects based on capacitor.config.ts. +5. Open native projects: + - Use the CLI to open each platform in its respective IDE for further customization. +6. Build and run: + - Build the web assets (as configured by your bundler), then use the CLI to run on device/emulator. + +Notes: +- Ensure the bundler’s output directory matches the webDir setting in capacitor.config.ts. +- After modifying plugins or configuration, always re-sync before rebuilding native projects. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) +- [mobile/README.md](file://mobile/README.md) + +### Environment Variables and Debugging +Environment variables: +- Define build-time variables in your bundler configuration and access them in the app where appropriate. +- For runtime variables, consider loading them from a secure source or configuration endpoint. + +Debugging: +- iOS: Enable Safari Web Inspector and connect the simulator/device to inspect WebView. +- Android: Use Chrome DevTools via chrome://inspect to attach to the WebView. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [src/mobile.js](file://src/mobile.js) +- [mobile/README.md](file://mobile/README.md) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Mobile Application/Mobile Application.md b/.qoder/repowiki/en/content/Mobile Application/Mobile Application.md new file mode 100644 index 0000000..205be8c --- /dev/null +++ b/.qoder/repowiki/en/content/Mobile Application/Mobile Application.md @@ -0,0 +1,400 @@ +# Mobile Application + + +**Referenced Files in This Document** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [index.html](file://index.html) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [supabase/config.toml](file://supabase/config.toml) +- [mobile/README.md](file://mobile/README.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document provides comprehensive mobile application documentation for ApplyGuard PH’s Capacitor-based app. It covers cross-platform setup, native feature access, mobile-specific optimizations, service worker implementation for offline functionality and background tasks, UI adaptations for touch interactions, device capability detection, build processes for iOS and Android, signing requirements, app store deployment procedures, debugging strategies, testing approaches, and performance considerations. + +## Project Structure +The project is a web-first application packaged as a native app using Capacitor. The key mobile-related assets include: +- Capacitor configuration file at the repository root +- A mobile entrypoint module that initializes Capacitor features +- Service worker and web manifest for PWA capabilities +- Build and hosting configurations for Vite and CI +- Supabase configuration for backend integration + +```mermaid +graph TB +subgraph "Web App" +index_html["index.html"] +vite_cfg["vite.config.js"] +package_json["package.json"] +end +subgraph "Capacitor" +cap_config["capacitor.config.ts"] +mobile_js["src/mobile.js"] +end +subgraph "PWA" +sw_js["public/sw.js"] +manifest["public/manifest.webmanifest"] +end +subgraph "Hosting & CI" +netlify["netlify.toml"] +vercel["vercel.json"] +end +subgraph "Backend" +supabase_cfg["supabase/config.toml"] +end +index_html --> cap_config +index_html --> mobile_js +index_html --> sw_js +index_html --> manifest +vite_cfg --> package_json +cap_config --> mobile_js +cap_config --> sw_js +cap_config --> manifest +netlify --> index_html +vercel --> index_html +supabase_cfg --> index_html +``` + +**Diagram sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [index.html](file://index.html) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [supabase/config.toml](file://supabase/config.toml) + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [index.html](file://index.html) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [supabase/config.toml](file://supabase/config.toml) + +## Core Components +- Capacitor Configuration: Centralizes app identity, web asset path, and plugin settings to bridge web code with native platforms. +- Mobile Entrypoint: Initializes Capacitor runtime and any platform-specific bootstrapping logic before the main app loads. +- Service Worker: Provides caching strategies, offline support, and optional background processing hooks. +- Web Manifest: Defines installability, icons, theme colors, and launch behavior for PWA and native packaging. +- Build and Hosting Configurations: Configure Vite bundling and deployment targets (Netlify/Vercel). +- Supabase Configuration: Backend environment and function definitions used by the app. + +Key responsibilities: +- Cross-platform compatibility via Capacitor plugins and web APIs +- Offline-first data handling through the service worker +- Device capability detection and graceful fallbacks +- Touch-friendly UI patterns and responsive layouts +- Secure builds and signing for app stores + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [supabase/config.toml](file://supabase/config.toml) + +## Architecture Overview +The mobile architecture layers the web application over Capacitor, which exposes native capabilities to JavaScript. The service worker handles caching and offline scenarios, while the web manifest ensures proper installation and presentation on devices. + +```mermaid +graph TB +User["User"] +WebView["Native WebView
iOS/Android"] +Capacitor["Capacitor Runtime"] +Plugins["Capacitor Plugins"] +WebApp["Web App Bundle
(Vite)"] +SW["Service Worker"] +Cache["Cache Storage"] +Network["Network"] +Backend["Supabase Functions"] +User --> WebView +WebView --> Capacitor +Capacitor --> Plugins +Capacitor --> WebApp +WebApp --> SW +SW --> Cache +SW --> Network +WebApp --> Network +Network --> Backend +``` + +**Diagram sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +## Detailed Component Analysis + +### Capacitor Setup and Cross-Platform Compatibility +- App Identity and Bundles: The configuration defines the app identifier, bundle names, and web asset directory so Capacitor can generate native projects. +- Plugin Integration: Capacitor plugins are referenced here to enable native features such as storage, camera, or push notifications. +- Web Path Mapping: Ensures the built web assets are correctly served from the native container. + +Operational notes: +- After updating the configuration, regenerate native projects and rebuild each platform. +- Keep plugin versions aligned across iOS and Android to avoid inconsistencies. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) + +### Mobile Entrypoint Initialization +- Bootstraps Capacitor before the main application renders. +- Optionally configures global listeners for lifecycle events (e.g., resume/pause) and error boundaries. +- Prepares device capability checks and feature flags for UI adaptation. + +Best practices: +- Defer heavy initialization until after Capacitor is ready. +- Use try/catch around native calls to handle unsupported environments gracefully. + +**Section sources** +- [mobile.js](file://src/mobile.js) + +### Service Worker Implementation for Offline Functionality +Responsibilities: +- Caching static assets and API responses to support offline usage. +- Implementing cache-first or network-first strategies per resource type. +- Handling background sync where supported. +- Providing update notifications when new content is available. + +Considerations: +- Ensure precache includes critical shell assets for fast cold starts. +- Validate cache keys to prevent stale data issues. +- Test both online and offline flows thoroughly. + +**Section sources** +- [public/sw.js](file://public/sw.js) + +### Web Manifest and Installability +Defines: +- App name, short name, description, and theme colors. +- Icons for various densities and splash screens. +- Display mode and orientation preferences. + +Impact: +- Enables add-to-home-screen prompts on supported browsers. +- Influences how the app appears when launched from the home screen. + +**Section sources** +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + +### Build Processes and Hosting Configuration +- Vite Configuration: Controls output format, asset handling, and environment variables. +- Package Scripts: Includes commands for building web assets and syncing with Capacitor. +- Hosting: Netlify and Vercel configs define redirects, headers, and SPA routing. + +Build flow overview: +```mermaid +flowchart TD +Start(["Start Build"]) --> Vite["Run Vite Build"] +Vite --> Assets["Generate Static Assets"] +Assets --> CapacitorSync["Capacitor Sync"] +CapacitorSync --> NativeProjects["Update iOS/Android Projects"] +NativeProjects --> End(["Ready for Platform Builds"]) +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [capacitor.config.ts](file://capacitor.config.ts) + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +### Push Notifications and Background Processing +Capabilities: +- Register for push permissions on iOS and Android. +- Handle token registration and message delivery. +- Process background tasks via platform-specific mechanisms. + +Implementation guidance: +- Integrate Capacitor push notification plugins. +- Manage tokens securely and refresh them on changes. +- Provide user-visible feedback for permission prompts. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) + +### Mobile UI Adaptations and Touch Interactions +Recommendations: +- Use large tap targets and spacing suitable for fingers. +- Avoid hover-dependent interactions; rely on click/tap semantics. +- Implement swipe gestures for navigation where appropriate. +- Respect safe areas and dynamic island notches on modern devices. + +Device capability detection: +- Detect touch availability, viewport size, and OS/browser features. +- Gracefully degrade features unavailable on certain devices. + +**Section sources** +- [mobile.js](file://src/mobile.js) +- [index.html](file://index.html) + +### Device Capability Detection and Feature Flags +Approach: +- Probe navigator and window APIs for presence of features. +- Maintain a feature flag map to conditionally render UI or disable non-functional actions. +- Provide clear messaging when features are unavailable. + +**Section sources** +- [mobile.js](file://src/mobile.js) + +### Signing Requirements and App Store Deployment +General steps: +- Generate platform-specific keystore/signing keys. +- Configure signing in Gradle (Android) and Xcode (iOS). +- Create release builds and run integrity checks. +- Submit binaries to Google Play and Apple App Store following their guidelines. + +Notes: +- Keep secrets out of version control; use secure secret managers. +- Automate signing in CI pipelines for consistency. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) + +### Debugging and Testing Strategies +Debugging: +- Use browser DevTools for web-layer debugging. +- Inspect native logs via Android Studio and Xcode. +- Enable verbose logging during development builds. + +Testing: +- Unit tests for business logic and utilities. +- E2E tests for critical user flows. +- Manual testing on real devices for native features and performance. + +**Section sources** +- [package.json](file://package.json) +- [mobile.js](file://src/mobile.js) + +## Dependency Analysis +High-level dependencies: +- Capacitor core and plugins provide native bridges. +- Vite orchestrates bundling and asset optimization. +- Hosting configurations ensure correct routing and caching headers. +- Supabase configuration drives backend endpoints and functions. + +```mermaid +graph LR +CapCfg["capacitor.config.ts"] --> Plugins["Capacitor Plugins"] +MobileJS["src/mobile.js"] --> CapRuntime["Capacitor Runtime"] +ViteCfg["vite.config.js"] --> Bundle["Web Bundle"] +SW["public/sw.js"] --> Cache["Cache Storage"] +Manifest["public/manifest.webmanifest"] --> Install["Installability"] +Netlify["netlify.toml"] --> Deploy["Deployment"] +Vercel["vercel.json"] --> Deploy +SupCfg["supabase/config.toml"] --> Backend["Backend Services"] +``` + +**Diagram sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [vite.config.js](file://vite.config.js) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [supabase/config.toml](file://supabase/config.toml) + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [vite.config.js](file://vite.config.js) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [supabase/config.toml](file://supabase/config.toml) + +## Performance Considerations +- Minimize initial payload: leverage Vite’s code splitting and tree-shaking. +- Precache only essential assets; implement dynamic caching for API responses. +- Debounce and throttle frequent native calls (camera, sensors). +- Use efficient image formats and sizes; lazy-load media. +- Monitor memory usage on low-end devices; avoid long-running JS tasks on the main thread. +- Profile with device-specific tools (Chrome DevTools, Android Profiler, Instruments). + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Capacitor sync failures: Re-run sync and verify web asset paths. +- Push notification permission denied: Re-prompt users with clear explanations. +- Offline errors: Validate cache keys and fallback strategies in the service worker. +- Build signing errors: Confirm keystore validity and password correctness. +- Routing issues on SPA hosting: Verify redirect rules in hosting configs. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [public/sw.js](file://public/sw.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +## Conclusion +ApplyGuard PH’s mobile app leverages Capacitor to deliver a consistent cross-platform experience while retaining the flexibility of web technologies. With a robust service worker, thoughtful UI adaptations, and disciplined build and deployment practices, the app achieves strong offline support, native feature access, and reliable performance across iOS and Android. Following the guidance in this document will help maintain quality, security, and scalability as the app evolves. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Quick Start Checklist +- Update Capacitor configuration for app identity and plugins. +- Initialize mobile entrypoint and device capability checks. +- Configure service worker caching strategies and update notifications. +- Define web manifest for installability and appearance. +- Set up Vite build scripts and hosting configurations. +- Prepare signing credentials and automate releases. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +### Additional Resources +- Mobile README for platform-specific notes and instructions. + +**Section sources** +- [mobile/README.md](file://mobile/README.md) \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Mobile Application/Mobile Development Workflow.md b/.qoder/repowiki/en/content/Mobile Application/Mobile Development Workflow.md new file mode 100644 index 0000000..5b7479a --- /dev/null +++ b/.qoder/repowiki/en/content/Mobile Application/Mobile Development Workflow.md @@ -0,0 +1,332 @@ +# Mobile Development Workflow + + +**Referenced Files in This Document** +- [src/mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile/README.md](file://mobile/README.md) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [index.html](file://index.html) +- [manifest.webmanifest](file://public/manifest.webmanifest) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document describes the mobile development workflow for ApplyGuard PH. It focuses on the mobile-specific entry point, service worker implementation for offline functionality, build process adaptations, hot reloading, debugging techniques, testing strategies, responsive design guidelines, touch interactions, device capability detection, performance optimization, memory management, and battery usage considerations. The goal is to help developers build, run, debug, and optimize the app across web and native mobile targets. + +## Project Structure +The project is a modern web application configured for both browser and mobile distribution: +- Web runtime entry points are under src/. +- A mobile-specific entry point exists at src/mobile.js. +- A PWA service worker is located at public/sw.js. +- Capacitor configuration is defined in capacitor.config.ts. +- Build tooling uses Vite via vite.config.js. +- The PWA manifest is at public/manifest.webmanifest. +- The HTML shell is index.html. +- The mobile folder contains mobile-specific guidance (mobile/README.md). + +```mermaid +graph TB +subgraph "Source" +A["src/mobile.js"] +B["src/main.jsx"] +C["src/App.jsx"] +D["src/store.jsx"] +E["src/components/*"] +F["src/lib/*"] +end +subgraph "PWA" +G["public/sw.js"] +H["public/manifest.webmanifest"] +I["index.html"] +end +subgraph "Build & Config" +J["vite.config.js"] +K["capacitor.config.ts"] +L["package.json"] +end +A --> C +B --> C +C --> D +C --> E +C --> F +I --> A +I --> B +I --> H +J --> A +J --> B +K --> A +K --> B +L --> J +L --> K +``` + +**Diagram sources** +- [src/mobile.js](file://src/mobile.js) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) +- [index.html](file://index.html) +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [package.json](file://package.json) + +**Section sources** +- [src/mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile/README.md](file://mobile/README.md) +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) +- [index.html](file://index.html) +- [manifest.webmanifest](file://public/manifest.webmanifest) + +## Core Components +- Mobile entry point: src/mobile.js initializes the app for mobile contexts and may set up mobile-specific behaviors or feature flags. +- Service worker: public/sw.js provides caching and offline support for PWA features. +- Capacitor config: capacitor.config.ts defines how the web build is wrapped into a native container. +- Build config: vite.config.js controls bundling, asset handling, and environment variables used by both web and mobile builds. +- Manifest: public/manifest.webmanifest declares PWA metadata such as name, icons, theme color, and display mode. + +Key responsibilities: +- Mobile entry point: ensure correct initialization path, detect mobile context if needed, and configure any mobile-only behavior. +- Service worker: cache critical assets, handle network-first vs cache-first strategies, and manage background sync where applicable. +- Capacitor: map web assets to native bundle, define permissions, and configure platform-specific options. +- Build: enable production optimizations, code splitting, and asset fingerprinting; expose environment variables for mobile builds. + +**Section sources** +- [src/mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [vite.config.js](file://vite.config.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + +## Architecture Overview +The mobile architecture layers include: +- UI layer: React components and hooks under src/components and src/hooks. +- State and data: store and lib modules for local state, Supabase integration, and utilities. +- Runtime entry: src/mobile.js for mobile and src/main.jsx for general web. +- PWA layer: service worker and manifest for offline and installability. +- Native wrapper: Capacitor bridges web assets to iOS/Android. + +```mermaid +sequenceDiagram +participant Dev as "Developer" +participant Vite as "Vite Dev Server" +participant Browser as "Browser / WebView" +participant SW as "Service Worker" +participant Cap as "Capacitor Runtime" +Dev->>Vite : Start dev server +Vite-->>Browser : Serve app + HMR updates +Browser->>SW : Register service worker +SW-->>Browser : Cache assets / respond offline +Dev->>Cap : Build for mobile +Cap-->>Browser : Load built assets in native WebView +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [src/mobile.js](file://src/mobile.js) +- [public/sw.js](file://public/sw.js) +- [capacitor.config.ts](file://capacitor.config.ts) + +## Detailed Component Analysis + +### Mobile Entry Point (src/mobile.js) +Purpose: +- Initialize the application when running in mobile contexts. +- Optionally apply mobile-specific feature flags, routing, or UI adjustments. +- Ensure compatibility with Capacitor’s WebView environment. + +Typical responsibilities: +- Detect mobile environment if necessary. +- Configure global settings or polyfills required only on mobile. +- Mount the root component or bootstrap logic tailored for mobile. + +Best practices: +- Keep mobile-specific logic isolated to avoid impacting web builds. +- Use environment checks rather than hardcoding platform assumptions. +- Avoid heavy work during startup; defer non-critical tasks. + +**Section sources** +- [src/mobile.js](file://src/mobile.js) + +### Service Worker Implementation (public/sw.js) +Purpose: +- Provide offline access to core app resources. +- Improve perceived performance through caching strategies. +- Enable installation and background capabilities per PWA standards. + +Common patterns: +- Precache essential assets during install. +- Network-first for dynamic content; cache-first for static assets. +- Handle fetch events to serve cached responses when offline. +- Manage cache versions and cleanup outdated entries. + +Operational notes: +- Ensure the service worker is registered from the HTML shell. +- Validate that the manifest references the service worker scope correctly. +- Test offline scenarios thoroughly across devices. + +**Section sources** +- [public/sw.js](file://public/sw.js) +- [index.html](file://index.html) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + +### Build Process Adaptations (vite.config.js) +Purpose: +- Configure bundling for both web and mobile distributions. +- Optimize assets, code splitting, and environment variable injection. +- Integrate with Capacitor’s expected output structure. + +Considerations: +- Set appropriate base paths for Capacitor’s www directory. +- Enable production optimizations (minification, tree-shaking). +- Expose environment variables for mobile-specific toggles. +- Ensure assets are properly hashed for cache busting. + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [package.json](file://package.json) + +### Capacitor Configuration (capacitor.config.ts) +Purpose: +- Define how the web build is packaged into native apps. +- Configure app metadata, permissions, and platform-specific options. +- Map web assets to the native container’s www folder. + +Guidelines: +- Align app ID, version, and name with store requirements. +- Configure plugins and permissions as needed (e.g., storage, camera). +- Verify that the web build output matches Capacitor’s expectations. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) + +### Mobile README Guidance (mobile/README.md) +Purpose: +- Provide team-specific instructions for building, running, and debugging mobile builds. +- Outline platform setup steps and common pitfalls. + +Usage: +- Follow platform prerequisites and CLI commands documented here. +- Refer to troubleshooting tips for known issues. + +**Section sources** +- [mobile/README.md](file://mobile/README.md) + +## Dependency Analysis +High-level dependencies: +- src/mobile.js depends on the app’s root component and shared libraries. +- public/sw.js is independent but interacts with the browser runtime and cache APIs. +- vite.config.js influences all source files by controlling build outputs. +- capacitor.config.ts consumes the build output produced by Vite. + +```mermaid +graph LR +Vite["vite.config.js"] --> Build["Build Output"] +Build --> Cap["capacitor.config.ts"] +Build --> SW["public/sw.js"] +Build --> HTML["index.html"] +HTML --> MobileEntry["src/mobile.js"] +MobileEntry --> App["src/App.jsx"] +App --> Store["src/store.jsx"] +App --> Components["src/components/*"] +App --> Libs["src/lib/*"] +``` + +**Diagram sources** +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [public/sw.js](file://public/sw.js) +- [index.html](file://index.html) +- [src/mobile.js](file://src/mobile.js) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) + +**Section sources** +- [vite.config.js](file://vite.config.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [public/sw.js](file://public/sw.js) +- [index.html](file://index.html) +- [src/mobile.js](file://src/mobile.js) +- [src/App.jsx](file://src/App.jsx) +- [src/store.jsx](file://src/store.jsx) + +## Performance Considerations +General guidance: +- Prefer lazy loading for heavy routes and components to reduce initial payload. +- Use efficient image formats and sizes; leverage responsive images where possible. +- Minimize synchronous work on the main thread; offload long-running tasks to workers if needed. +- Leverage caching strategies in the service worker to reduce network requests. +- Profile memory usage regularly; avoid retaining large objects unnecessarily. +- Monitor battery impact by reducing frequent polling and heavy animations. + +Mobile-specific tips: +- Avoid blocking the UI thread during app start-up; defer non-critical initialization. +- Use hardware acceleration judiciously; excessive compositing can increase power usage. +- Respect system preferences like reduced motion and dark mode. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common areas to inspect: +- Service worker registration and lifecycle: verify registration from the HTML shell and check cache states. +- Capacitor build output: ensure the www directory structure matches expectations. +- Environment variables: confirm they are injected correctly for mobile builds. +- Device permissions: validate that required permissions are declared and requested appropriately. + +Debugging techniques: +- Use browser DevTools for web previews and PWA inspection. +- Use platform-native debuggers (Xcode for iOS, Android Studio for Android) when running inside Capacitor. +- Inspect logs from the native WebView and plugin calls. + +Testing strategies: +- Test on real devices to validate touch interactions, orientation changes, and performance. +- Simulate offline conditions to verify service worker behavior. +- Run automated tests for critical flows and unit tests for utility modules. + +**Section sources** +- [public/sw.js](file://public/sw.js) +- [index.html](file://index.html) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile/README.md](file://mobile/README.md) + +## Conclusion +By isolating mobile-specific logic in the mobile entry point, implementing a robust service worker, and aligning build and packaging configurations, ApplyGuard PH can deliver a performant, offline-capable experience across web and native mobile platforms. Following the outlined debugging, testing, and optimization practices will help maintain quality and responsiveness on diverse devices. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Responsive Design Guidelines +- Use fluid layouts and relative units to adapt to various screen sizes. +- Implement breakpoints for small, medium, and large screens. +- Ensure text remains readable and interactive elements meet minimum touch target sizes. + +### Touch Interactions +- Support tap, swipe, and pinch gestures where appropriate. +- Provide visual feedback for touch actions. +- Avoid hover-dependent interactions; rely on focus and active states. + +### Device Capability Detection +- Feature-detect APIs before use rather than relying solely on user agent strings. +- Gracefully degrade functionality when advanced features are unavailable. +- Use progressive enhancement to improve experiences on capable devices. + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Mobile Application/Native Platform Integrations.md b/.qoder/repowiki/en/content/Mobile Application/Native Platform Integrations.md new file mode 100644 index 0000000..d6ee750 --- /dev/null +++ b/.qoder/repowiki/en/content/Mobile Application/Native Platform Integrations.md @@ -0,0 +1,342 @@ +# Native Platform Integrations + + +**Referenced Files in This Document** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [package.json](file://package.json) +- [README.md](file://README.md) + + +## Table of Contents +1. [Introduction](#introduction) +2. [Project Structure](#project-structure) +3. [Core Components](#core-components) +4. [Architecture Overview](#architecture-overview) +5. [Detailed Component Analysis](#detailed-component-analysis) +6. [Dependency Analysis](#dependency-analysis) +7. [Performance Considerations](#performance-considerations) +8. [Troubleshooting Guide](#troubleshooting-guide) +9. [Conclusion](#conclusion) +10. [Appendices](#appendices) + +## Introduction +This document explains how ApplyGuard PH integrates with native platform capabilities on iOS and Android using Capacitor. It covers available Capacitor plugins, patterns for accessing native APIs, permission handling, and guidance for camera access, file system operations, push notifications, and device sensors. It also includes error handling strategies, fallback mechanisms for unsupported features, platform-specific considerations, security implications, and user privacy requirements. + +## Project Structure +The mobile integration is configured at the project root and wired into the application via a dedicated module. The key files are: +- capacitor.config.ts: Capacitor configuration (app ID, name, webDir, plugins, etc.) +- src/mobile.js: Mobile entrypoint that initializes Capacitor and conditionally loads native-capable modules +- package.json: Declares dependencies including Capacitor runtime and any native plugins used by the app +- README.md: General project overview and setup notes + +```mermaid +graph TB +A["capacitor.config.ts"] --> B["Capacitor Runtime"] +C["src/mobile.js"] --> B +D["package.json"] --> B +E["Web App (Vite build)"] --> C +B --> F["iOS Native Bridge"] +B --> G["Android Native Bridge"] +``` + +**Diagram sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [package.json](file://package.json) + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [package.json](file://package.json) +- [README.md](file://README.md) + +## Core Components +- Capacitor Configuration + - Defines app metadata, web directory, and plugin settings to ensure correct bridging between web code and native platforms. + - Typical keys include app identifier, app name, web asset directory, and per-plugin options. + +- Mobile Entrypoint + - Initializes Capacitor at app startup and conditionally enables native features only when running inside a native container. + - Provides a safe place to register listeners or initialize services that require native context. + +- Dependency Management + - Declares Capacitor core and any additional plugins required for camera, storage, notifications, and sensors. + - Ensures consistent versions across web and native builds. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [package.json](file://package.json) + +## Architecture Overview +At runtime, the web application runs inside a WebView provided by Capacitor. JavaScript calls into Capacitor’s bridge, which forwards requests to native implementations on iOS and Android. Responses flow back through the bridge to the web layer. + +```mermaid +sequenceDiagram +participant Web as "Web App" +participant JS as "Capacitor JS Bridge" +participant IOS as "iOS Native Bridge" +participant AND as "Android Native Bridge" +Web->>JS : "Call native API" +JS->>IOS : "Forward to iOS implementation" +JS->>AND : "Forward to Android implementation" +IOS-->>JS : "Result/Error" +AND-->>JS : "Result/Error" +JS-->>Web : "Promise resolved/rejected" +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### Capacitor Plugins and Available Features +- Camera Access + - Use the official Capacitor Camera plugin to capture photos or select images from the gallery. + - Request permissions before invoking camera actions. + - Handle errors such as denied permissions, canceled operations, or missing hardware. + +- File System Operations + - Prefer Capacitor Storage for small key-value data and app-scoped preferences. + - For larger files or cross-app sharing, use Capacitor Filesystem to read/write within the app’s sandboxed directories. + - Respect platform-specific paths and avoid writing outside allowed locations. + +- Push Notifications + - Integrate with Capacitor Push Notifications to register devices, handle token updates, and process incoming messages. + - On iOS, configure APNs certificates and entitlements; on Android, configure Firebase and manifest entries. + - Gracefully degrade if push is unavailable or disabled by the user. + +- Device Sensors + - Use Capacitor Device plugin for basic device info and battery status. + - For motion and orientation, use Capacitor Motion or Accelerometer where appropriate. + - Always check availability and handle lack of sensor hardware or disabled sensors. + +- Clipboard + - Read/write clipboard content using Capacitor Clipboard for copy/paste flows. + - Avoid reading sensitive data without explicit user action. + +- Share + - Use Capacitor Share to open native share sheets for text, URLs, or files. + +- In-App Browser + - Open external links securely using Capacitor InAppBrowser with appropriate options. + +- Geolocation + - Use Capacitor Geolocation to obtain location with proper permission prompts and background restrictions. + +- Network Status + - Use Capacitor Network to detect connectivity changes and adapt behavior accordingly. + +- App Lifecycle + - Use Capacitor App to listen to lifecycle events like resume/suspend and act on them (e.g., pause/resume media). + +- Splash Screen + - Configure splash screen behavior via Capacitor config and hide programmatically after initialization. + +- Toast/Alerts + - Use Capacitor Toast or Alert for lightweight feedback and confirmations. + +- Secure Storage + - For secrets, prefer platform secure storage solutions exposed via Capacitor plugins or native modules. + +Permission Handling Patterns +- Check and request permissions before sensitive operations (camera, microphone, location, notifications). +- Provide clear UI explaining why permissions are needed. +- Handle denial gracefully with fallbacks or guided steps to enable permissions in system settings. + +Error Handling Strategies +- Wrap all native calls in try/catch or promise rejection handlers. +- Normalize errors into user-friendly messages. +- Log detailed diagnostics in development mode while avoiding sensitive data in logs. + +Fallback Mechanisms +- Detect feature availability and provide web-based alternatives when native features are absent. +- Disable premium/native-only features when permissions are denied or hardware is missing. +- Cache results locally to improve resilience during network outages. + +Platform-Specific Considerations +- iOS + - Ensure Info.plist contains usage descriptions for camera, photo library, location, microphone, and notifications. + - Configure APNs for push notifications and handle background modes if required. + - Be mindful of ATS and HTTPS requirements for network calls. + +- Android + - Add required permissions in AndroidManifest.xml (camera, storage, internet, notification, location). + - Configure Firebase for push notifications and test on real devices for accurate behavior. + - Use scoped storage and SAF for file operations on newer Android versions. + +Security Implications +- Never store tokens or secrets in plain text; use secure storage. +- Validate and sanitize inputs passed to native layers. +- Limit exposure of sensitive data in logs and analytics. +- Enforce HTTPS and certificate pinning where applicable. + +User Privacy Requirements +- Provide clear privacy notices and consent flows. +- Honor user choices to disable tracking or location. +- Minimize data collection and retain only what is necessary. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [package.json](file://package.json) + +### Camera Access Flow +```mermaid +flowchart TD +Start(["Open Camera"]) --> CheckPerm["Check Camera Permission"] +CheckPerm --> PermGranted{"Permission Granted?"} +PermGranted --> |Yes| Capture["Capture Image"] +PermGranted --> |No| PromptPerm["Request Permission"] +PromptPerm --> PermGranted2{"Permission Granted?"} +PermGranted2 --> |No| Fallback["Show Guidance to Enable in Settings"] +PermGranted2 --> |Yes| Capture +Capture --> Result{"Success?"} +Result --> |Yes| Process["Process Image Data"] +Result --> |No| HandleErr["Handle Error/Canceled"] +Process --> End(["Done"]) +HandleErr --> End +Fallback --> End +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +### File System Operations Flow +```mermaid +flowchart TD +Start(["File Operation"]) --> ChooseTarget["Choose Target Directory"] +ChooseTarget --> WriteOrRead{"Write or Read?"} +WriteOrRead --> |Write| ValidatePath["Validate Path Within Sandbox"] +ValidatePath --> PerformWrite["Perform Write"] +WriteOrRead --> |Read| PerformRead["Perform Read"] +PerformWrite --> Success{"Success?"} +PerformRead --> Success +Success --> |Yes| ReturnData["Return Data/Path"] +Success --> |No| HandleError["Handle I/O Error"] +ReturnData --> End(["Done"]) +HandleError --> End +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +### Push Notifications Flow +```mermaid +sequenceDiagram +participant App as "App" +participant PN as "Push Notifications Plugin" +participant OS as "OS Notification Service" +App->>PN : "Initialize and request permission" +PN->>OS : "Register for notifications" +OS-->>PN : "Token/Status" +PN-->>App : "On message received" +App->>App : "Update UI / Persist payload" +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +### Device Sensors Integration +```mermaid +classDiagram +class DevicePlugin { ++getDeviceInfo() ++getBatteryStatus() +} +class MotionPlugin { ++startListening() ++stopListening() ++onMotionChange(callback) +} +class App { ++useDeviceFeatures() +} +App --> DevicePlugin : "uses" +App --> MotionPlugin : "uses" +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Dependency Analysis +The following diagram maps the primary integration points between configuration, runtime, and native bridges. + +```mermaid +graph TB +Pkg["package.json"] --> CapCfg["capacitor.config.ts"] +CapCfg --> CapRuntime["Capacitor Runtime"] +MobileEntry["src/mobile.js"] --> CapRuntime +CapRuntime --> IOSBridge["iOS Native Bridge"] +CapRuntime --> ANDBridge["Android Native Bridge"] +``` + +**Diagram sources** +- [package.json](file://package.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) + +**Section sources** +- [package.json](file://package.json) +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) + +## Performance Considerations +- Batch native calls where possible to reduce bridge overhead. +- Debounce frequent sensor updates and throttle UI re-renders. +- Cache frequently accessed data locally to minimize repeated native/file reads. +- Avoid heavy image processing on the main thread; offload to workers or native code when feasible. +- Monitor memory usage for large file operations and release resources promptly. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Permission Denied + - Verify Info.plist and AndroidManifest.xml contain required usage descriptions and permissions. + - Implement permission checks and guide users to system settings when denied. + +- Push Not Working + - Confirm APNs/Firebase configurations and provisioning profiles. + - Test on physical devices; simulators may have limited support. + +- File I/O Failures + - Ensure target directories exist and are writable within the app sandbox. + - Handle scoped storage constraints on Android. + +- Camera Errors + - Check for hardware availability and permission state. + - Handle canceled captures and invalid image formats. + +- Network Issues + - Use Network plugin to detect offline states and queue operations for later sync. + +- Build/Run Problems + - Rebuild native projects after adding new plugins. + - Sync Capacitor with latest versions and regenerate platforms. + +**Section sources** +- [capacitor.config.ts](file://capacitor.config.ts) +- [mobile.js](file://src/mobile.js) +- [package.json](file://package.json) + +## Conclusion +ApplyGuard PH leverages Capacitor to integrate native capabilities seamlessly across iOS and Android. By configuring the app correctly, initializing the bridge early, and adopting robust permission and error-handling patterns, the app can deliver rich native experiences while maintaining strong security and privacy standards. When native features are unavailable, graceful fallbacks ensure a consistent user experience. + +[No sources needed since this section summarizes without analyzing specific files] + +## Appendices + +### Quick Reference: Common Capacitor Plugins +- Camera: Capture and select images +- Filesystem: Read/write within app sandbox +- Storage: Key-value preferences +- Push Notifications: Register and receive notifications +- Device: Basic device info and battery status +- Motion/Accelerometer: Sensor data streams +- Clipboard: Copy/paste operations +- Share: Native share sheet +- InAppBrowser: Secure external link handling +- Geolocation: Location access with permissions +- Network: Connectivity monitoring +- App: Lifecycle events +- Splash Screen: Boot splash control +- Toast/Alert: Lightweight feedback + +[No sources needed since this section provides general guidance] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Project Overview.md b/.qoder/repowiki/en/content/Project Overview.md new file mode 100644 index 0000000..aa29ca2 --- /dev/null +++ b/.qoder/repowiki/en/content/Project Overview.md @@ -0,0 +1,514 @@ +# Project Overview + + +**Referenced Files in This Document** +- [README.md](file://README.md) +- [package.json](file://package.json) +- [src/main.jsx](file://src/main.jsx) +- [src/App.jsx](file://src/App.jsx) +- [src/auth.jsx](file://src/auth.jsx) +- [src/store.jsx](file://src/store.jsx) +- [src/mobile.js](file://src/mobile.js) +- [capacitor.config.ts](file://capacitor.config.ts) +- [supabase/config.toml](file://supabase/config.toml) +- [supabase/migrations/001_schema.sql](file://supabase/migrations/001_schema.sql) +- [supabase/migrations/002_paypal_fulfillment.sql](file://supabase/migrations/002_paypal_fulfillment.sql) +- [supabase/functions/_shared/http.ts](file://supabase/functions/_shared/http.ts) +- [supabase/functions/_shared/paypal.ts](file://supabase/functions/_shared/paypal.ts) +- [supabase/functions/_shared/paypal-runtime.ts](file://supabase/functions/_shared/paypal-runtime.ts) +- [supabase/functions/_shared/entitlement.ts](file://supabase/functions/_shared/entitlement.ts) +- [supabase/functions/create-checkout/index.ts](file://supabase/functions/create-checkout/index.ts) +- [supabase/functions/capture-paypal-order/index.ts](file://supabase/functions/capture-paypal-order/index.ts) +- [supabase/functions/create-paypal-order/index.ts](file://supabase/functions/create-paypal-order/index.ts) +- [supabase/functions/paymongo-webhook/index.ts](file://supabase/functions/paymongo-webhook/index.ts) +- [supabase/functions/paypal-webhook/index.ts](file://supabase/functions/paypal-webhook/index.ts) +- [supabase/functions/ai-proxy/index.ts](file://supabase/functions/ai-proxy/index.ts) +- [src/lib/supabase.js](file://src/lib/supabase.js) +- [src/lib/billing.js](file://src/lib/billing.js) +- [src/lib/entitlement.js](file://src/lib/entitlement.js) +- [src/components/AiAssistant.jsx](file://src/components/AiAssistant.jsx) +- [src/components/MockInterviewPage.jsx](file://src/components/MockInterviewPage.jsx) +- [src/components/OffersPage.jsx](file://src/components/OffersPage.jsx) +- [src/components/ScanForm.jsx](file://src/components/ScanForm.jsx) +- [src/components/Tracker.jsx](file://src/components/Tracker.jsx) +- [src/components/ResultView.jsx](file://src/components/ResultView.jsx) +- [src/components/AccountPage.jsx](file://src/components/AccountPage.jsx) +- [src/components/Layout.jsx](file://src/components/Layout.jsx) +- [src/components/Settings.jsx](file://src/components/Settings.jsx) +- [src/lib/analyze.js](file://src/lib/analyze.js) +- [src/lib/scoring.js](file://src/lib/scoring.js) +- [src/lib/redflags.js](file://src/lib/redflags.js) +- [src/lib/stats.js](file://src/lib/stats.js) +- [src/lib/followups.js](file://src/lib/followups.js) +- [src/lib/prompt.js](file://src/lib/prompt.js) +- [src/lib/ai.js](file://src/lib/ai.js) +- [src/lib/pricing.js](file://src/lib/pricing.js) +- [src/lib/cloud.js](file://src/lib/cloud.js) +- [src/lib/sync.js](file://src/lib/sync.js) +- [src/lib/storage.js](file://src/lib/storage.js) +- [public/sw.js](file://public/sw.js) +- [public/manifest.webmanifest](file://public/manifest.webmanifest) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion + +## Introduction +ApplyGuard PH is a job application tracking and analysis platform designed to help job seekers organize their applications, prepare for interviews, evaluate offers, and leverage AI-powered insights to improve outcomes. The platform combines a modern web experience with mobile support and secure cloud storage, enabling users to track progress across devices and receive actionable feedback on resumes and interview performance. + +Key value propositions: +- Centralized application tracker with analytics and follow-up reminders +- AI-assisted resume scanning and interview preparation +- Offer comparison and decision support +- Subscription-based billing with multiple payment providers +- Cross-platform access via web and mobile (Capacitor) + +Target audience: +- Job seekers at all levels who want structured tracking and coaching +- Career coaches and mentors who need visibility into client pipelines +- Students and recent graduates preparing for first roles + +Primary use cases: +- Track applications from submission to offer or rejection +- Prepare for interviews using AI-driven mock sessions and feedback +- Compare offers side-by-side with weighted criteria +- Manage subscriptions and unlock premium features + +[No sources needed since this section provides general guidance] + +## Project Structure +The project follows a feature-oriented frontend layout with Supabase as the backend and serverless functions for payments and AI proxying. Mobile packaging is handled by Capacitor. + +Highlights: +- Frontend: React + Vite app under src/, organized by components and domain-specific libraries +- Backend: Supabase database and Edge Functions for billing and AI proxy +- Mobile: Capacitor configuration for building native apps from the same codebase +- PWA: Service worker and manifest for offline-friendly experiences + +```mermaid +graph TB +subgraph "Frontend" +A["App.jsx"] +B["main.jsx"] +C["store.jsx"] +D["auth.jsx"] +E["components/*"] +F["lib/*"] +end +subgraph "Supabase" +G["Database (migrations)"] +H["Edge Functions"] +end +subgraph "Mobile" +I["Capacitor (capacitor.config.ts)"] +end +subgraph "PWA" +J["sw.js"] +K["manifest.webmanifest"] +end +A --> E +A --> F +B --> A +C --> F +D --> F +E --> F +F --> G +F --> H +I --> B +J --> B +K --> B +``` + +**Diagram sources** +- [src/main.jsx:1-50](file://src/main.jsx#L1-L50) +- [src/App.jsx:1-120](file://src/App.jsx#L1-L120) +- [src/store.jsx:1-80](file://src/store.jsx#L1-L80) +- [src/auth.jsx:1-60](file://src/auth.jsx#L1-L60) +- [capacitor.config.ts:1-40](file://capacitor.config.ts#L1-L40) +- [public/sw.js:1-40](file://public/sw.js#L1-L40) +- [public/manifest.webmanifest:1-40](file://public/manifest.webmanifest#L1-L40) +- [supabase/migrations/001_schema.sql:1-60](file://supabase/migrations/001_schema.sql#L1-L60) +- [supabase/config.toml:1-40](file://supabase/config.toml#L1-L40) + +**Section sources** +- [README.md:1-60](file://README.md#L1-L60) +- [package.json:1-60](file://package.json#L1-L60) +- [src/main.jsx:1-50](file://src/main.jsx#L1-L50) +- [src/App.jsx:1-120](file://src/App.jsx#L1-L120) +- [capacitor.config.ts:1-40](file://capacitor.config.ts#L1-L40) +- [public/sw.js:1-40](file://public/sw.js#L1-L40) +- [public/manifest.webmanifest:1-40](file://public/manifest.webmanifest#L1-L40) +- [supabase/config.toml:1-40](file://supabase/config.toml#L1-L40) + +## Core Components +This section outlines the main user-facing features and how they are implemented in the frontend and backend. + +- Application Tracker + - Purpose: Track jobs, statuses, notes, and next actions + - Key files: Tracker component, stats and follow-ups utilities + - Data flow: Local state and Supabase sync; analytics computed from stored records + +- Resume Scanner and AI Assistant + - Purpose: Analyze resumes and provide improvement suggestions + - Key files: Scan form, result view, AI assistant, prompt builder, AI proxy function + - Data flow: User input -> local analysis helpers -> AI proxy -> results display + +- Mock Interview Preparation + - Purpose: Practice interviews with AI-driven questions and feedback + - Key files: Mock interview page, AI assistant integration + - Data flow: Scenario selection -> AI prompts -> interactive Q&A -> summary + +- Offers Management + - Purpose: Compare and manage job offers with scoring and notes + - Key files: Offers page, scoring utilities + - Data flow: Offer entries -> scoring model -> comparative views + +- Billing and Subscriptions + - Purpose: Manage plans, entitlements, and payments + - Key files: Billing library, entitlement checks, checkout and webhook functions + - Data flow: Checkout initiation -> payment provider -> webhook -> entitlement update + +- Account and Settings + - Purpose: User profile, preferences, and subscription management + - Key files: Account page, settings component, auth integration + +**Section sources** +- [src/components/Tracker.jsx:1-120](file://src/components/Tracker.jsx#L1-L120) +- [src/lib/stats.js:1-80](file://src/lib/stats.js#L1-L80) +- [src/lib/followups.js:1-80](file://src/lib/followups.js#L1-L80) +- [src/components/ScanForm.jsx:1-120](file://src/components/ScanForm.jsx#L1-L120) +- [src/components/ResultView.jsx:1-120](file://src/components/ResultView.jsx#L1-L120) +- [src/components/AiAssistant.jsx:1-120](file://src/components/AiAssistant.jsx#L1-L120) +- [src/lib/prompt.js:1-80](file://src/lib/prompt.js#L1-L80) +- [src/lib/ai.js:1-80](file://src/lib/ai.js#L1-L80) +- [supabase/functions/ai-proxy/index.ts:1-80](file://supabase/functions/ai-proxy/index.ts#L1-L80) +- [src/components/MockInterviewPage.jsx:1-120](file://src/components/MockInterviewPage.jsx#L1-L120) +- [src/components/OffersPage.jsx:1-120](file://src/components/OffersPage.jsx#L1-L120) +- [src/lib/scoring.js:1-80](file://src/lib/scoring.js#L1-L80) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-80](file://src/lib/entitlement.js#L1-L80) +- [src/components/AccountPage.jsx:1-120](file://src/components/AccountPage.jsx#L1-L120) +- [src/components/Settings.jsx:1-120](file://src/components/Settings.jsx#L1-L120) +- [src/auth.jsx:1-60](file://src/auth.jsx#L1-L60) + +## Architecture Overview +High-level architecture showing how the frontend interacts with Supabase, serverless functions, and optional mobile packaging. + +```mermaid +graph TB +U["User"] +FE["React App
src/main.jsx, src/App.jsx"] +AUTH["Auth Layer
src/auth.jsx"] +STORE["State Store
src/store.jsx"] +LIBS["Domain Libraries
src/lib/*"] +SB["Supabase DB
supabase/migrations/*"] +SF["Supabase Functions
billing, ai-proxy, webhooks"] +PAY["Payment Providers
PayPal, PayMongo"] +CAP["Capacitor Runtime
capacitor.config.ts"] +PWA["Service Worker & Manifest
public/sw.js, public/manifest.webmanifest"] +U --> FE +FE --> AUTH +FE --> STORE +FE --> LIBS +LIBS --> SB +LIBS --> SF +SF --> PAY +FE --> CAP +FE --> PWA +``` + +**Diagram sources** +- [src/main.jsx:1-50](file://src/main.jsx#L1-L50) +- [src/App.jsx:1-120](file://src/App.jsx#L1-L120) +- [src/auth.jsx:1-60](file://src/auth.jsx#L1-L60) +- [src/store.jsx:1-80](file://src/store.jsx#L1-L80) +- [src/lib/supabase.js:1-80](file://src/lib/supabase.js#L1-L80) +- [supabase/migrations/001_schema.sql:1-60](file://supabase/migrations/001_schema.sql#L1-L60) +- [supabase/migrations/002_paypal_fulfillment.sql:1-60](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L60) +- [supabase/functions/_shared/http.ts:1-80](file://supabase/functions/_shared/http.ts#L1-L80) +- [supabase/functions/_shared/paypal.ts:1-80](file://supabase/functions/_shared/paypal.ts#L1-L80) +- [supabase/functions/_shared/paypal-runtime.ts:1-80](file://supabase/functions/_shared/paypal-runtime.ts#L1-L80) +- [supabase/functions/_shared/entitlement.ts:1-80](file://supabase/functions/_shared/entitlement.ts#L1-L80) +- [supabase/functions/create-checkout/index.ts:1-80](file://supabase/functions/create-checkout/index.ts#L1-L80) +- [supabase/functions/capture-paypal-order/index.ts:1-80](file://supabase/functions/capture-paypal-order/index.ts#L1-L80) +- [supabase/functions/create-paypal-order/index.ts:1-80](file://supabase/functions/create-paypal-order/index.ts#L1-L80) +- [supabase/functions/paymongo-webhook/index.ts:1-80](file://supabase/functions/paymongo-webhook/index.ts#L1-L80) +- [supabase/functions/paypal-webhook/index.ts:1-80](file://supabase/functions/paypal-webhook/index.ts#L1-L80) +- [capacitor.config.ts:1-40](file://capacitor.config.ts#L1-L40) +- [public/sw.js:1-40](file://public/sw.js#L1-L40) +- [public/manifest.webmanifest:1-40](file://public/manifest.webmanifest#L1-L40) + +## Detailed Component Analysis + +### Resume Scanning and AI Assistance +This feature allows users to submit resume content for analysis and receive AI-generated feedback. It integrates with an AI proxy function to securely call external models while enforcing rate limits and logging. + +```mermaid +sequenceDiagram +participant User as "User" +participant UI as "ScanForm.jsx" +participant Lib as "analyze.js / redflags.js / scoring.js" +participant Prompt as "prompt.js" +participant Proxy as "ai-proxy/index.ts" +participant Model as "AI Provider" +participant View as "ResultView.jsx" +User->>UI : "Submit resume text" +UI->>Lib : "Preprocess and extract signals" +Lib-->>UI : "Structured analysis data" +UI->>Prompt : "Build context-aware prompt" +Prompt-->>UI : "Final prompt payload" +UI->>Proxy : "Send request with user context" +Proxy->>Model : "Call AI API" +Model-->>Proxy : "AI response" +Proxy-->>UI : "Normalized result" +UI->>View : "Render insights and recommendations" +``` + +**Diagram sources** +- [src/components/ScanForm.jsx:1-120](file://src/components/ScanForm.jsx#L1-L120) +- [src/lib/analyze.js:1-80](file://src/lib/analyze.js#L1-L80) +- [src/lib/redflags.js:1-80](file://src/lib/redflags.js#L1-L80) +- [src/lib/scoring.js:1-80](file://src/lib/scoring.js#L1-L80) +- [src/lib/prompt.js:1-80](file://src/lib/prompt.js#L1-L80) +- [supabase/functions/ai-proxy/index.ts:1-80](file://supabase/functions/ai-proxy/index.ts#L1-L80) +- [src/components/ResultView.jsx:1-120](file://src/components/ResultView.jsx#L1-L120) + +**Section sources** +- [src/components/ScanForm.jsx:1-120](file://src/components/ScanForm.jsx#L1-L120) +- [src/lib/analyze.js:1-80](file://src/lib/analyze.js#L1-L80) +- [src/lib/redflags.js:1-80](file://src/lib/redflags.js#L1-L80) +- [src/lib/scoring.js:1-80](file://src/lib/scoring.js#L1-L80) +- [src/lib/prompt.js:1-80](file://src/lib/prompt.js#L1-L80) +- [supabase/functions/ai-proxy/index.ts:1-80](file://supabase/functions/ai-proxy/index.ts#L1-L80) +- [src/components/ResultView.jsx:1-120](file://src/components/ResultView.jsx#L1-L120) + +### Mock Interview Preparation +Users can practice interviews through guided scenarios and receive AI feedback. The flow includes scenario selection, question generation, and post-session summaries. + +```mermaid +flowchart TD +Start(["Start Mock Session"]) --> Select["Select Scenario and Level"] +Select --> BuildPrompt["Build Prompt Context"] +BuildPrompt --> CallAI["Call AI Proxy"] +CallAI --> GenerateQ["Generate Questions"] +GenerateQ --> Interact["Interactive Q&A"] +Interact --> Summarize["Summarize Feedback"] +Summarize --> Save["Save Session Notes"] +Save --> End(["End Session"]) +``` + +**Diagram sources** +- [src/components/MockInterviewPage.jsx:1-120](file://src/components/MockInterviewPage.jsx#L1-L120) +- [src/components/AiAssistant.jsx:1-120](file://src/components/AiAssistant.jsx#L1-L120) +- [src/lib/prompt.js:1-80](file://src/lib/prompt.js#L1-L80) +- [supabase/functions/ai-proxy/index.ts:1-80](file://supabase/functions/ai-proxy/index.ts#L1-L80) + +**Section sources** +- [src/components/MockInterviewPage.jsx:1-120](file://src/components/MockInterviewPage.jsx#L1-L120) +- [src/components/AiAssistant.jsx:1-120](file://src/components/AiAssistant.jsx#L1-L120) +- [src/lib/prompt.js:1-80](file://src/lib/prompt.js#L1-L80) +- [supabase/functions/ai-proxy/index.ts:1-80](file://supabase/functions/ai-proxy/index.ts#L1-L80) + +### Offers Management and Scoring +The offers module helps compare multiple offers using configurable criteria and scoring logic. Users can adjust weights and see ranked comparisons. + +```mermaid +classDiagram +class OffersPage { ++renderOfferList() ++addOffer(data) ++updateOffer(id, data) ++deleteOffer(id) ++compareOffers() +} +class Scoring { ++computeScore(offer, weights) ++rankOffers(scores) ++exportSummary() +} +OffersPage --> Scoring : "uses" +``` + +**Diagram sources** +- [src/components/OffersPage.jsx:1-120](file://src/components/OffersPage.jsx#L1-L120) +- [src/lib/scoring.js:1-80](file://src/lib/scoring.js#L1-L80) + +**Section sources** +- [src/components/OffersPage.jsx:1-120](file://src/components/OffersPage.jsx#L1-L120) +- [src/lib/scoring.js:1-80](file://src/lib/scoring.js#L1-L80) + +### Subscription Billing and Entitlements +Billing flows integrate with PayPal and PayMongo via Supabase Edge Functions. Webhooks update entitlements and grant access to premium features. + +```mermaid +sequenceDiagram +participant Client as "Frontend (billing.js)" +participant Checkout as "create-checkout/index.ts" +participant PayPal as "PayPal API" +participant Capture as "capture-paypal-order/index.ts" +participant Webhook as "paypal-webhook/index.ts" +participant Entitle as "_shared/entitlement.ts" +participant DB as "Supabase DB" +Client->>Checkout : "Initiate checkout" +Checkout->>PayPal : "Create order" +PayPal-->>Checkout : "Order ID" +Checkout-->>Client : "Redirect to payment" +Client->>Capture : "Capture order after payment" +Capture->>DB : "Record transaction" +PayPal-->>Webhook : "Event notification" +Webhook->>Entitle : "Update entitlements" +Entitle->>DB : "Persist entitlement changes" +``` + +**Diagram sources** +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [supabase/functions/create-checkout/index.ts:1-80](file://supabase/functions/create-checkout/index.ts#L1-L80) +- [supabase/functions/capture-paypal-order/index.ts:1-80](file://supabase/functions/capture-paypal-order/index.ts#L1-L80) +- [supabase/functions/paypal-webhook/index.ts:1-80](file://supabase/functions/paypal-webhook/index.ts#L1-L80) +- [supabase/functions/_shared/entitlement.ts:1-80](file://supabase/functions/_shared/entitlement.ts#L1-L80) +- [supabase/migrations/002_paypal_fulfillment.sql:1-60](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L60) + +Additional integrations: +- PayMongo webhook handler for alternative payment processing +- Shared HTTP utilities and PayPal runtime helpers + +**Section sources** +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-80](file://src/lib/entitlement.js#L1-L80) +- [supabase/functions/_shared/http.ts:1-80](file://supabase/functions/_shared/http.ts#L1-L80) +- [supabase/functions/_shared/paypal.ts:1-80](file://supabase/functions/_shared/paypal.ts#L1-L80) +- [supabase/functions/_shared/paypal-runtime.ts:1-80](file://supabase/functions/_shared/paypal-runtime.ts#L1-L80) +- [supabase/functions/paymongo-webhook/index.ts:1-80](file://supabase/functions/paymongo-webhook/index.ts#L1-L80) +- [supabase/migrations/002_paypal_fulfillment.sql:1-60](file://supabase/migrations/002_paypal_fulfillment.sql#L1-L60) + +### Data Storage and Sync +Data persistence uses Supabase tables defined in migrations. The frontend leverages a shared Supabase client and sync utilities to keep local and remote states consistent. + +```mermaid +flowchart TD +Entry(["App Start"]) --> Init["Initialize Supabase Client"] +Init --> LoadSchema["Load Schema from Migrations"] +LoadSchema --> FetchData["Fetch Records"] +FetchData --> LocalCache["Local Cache / Storage"] +LocalCache --> Render["Render UI"] +Render --> Mutate["Mutate Data"] +Mutate --> Sync["Sync to Supabase"] +Sync --> UpdateCache["Update Local Cache"] +UpdateCache --> Render +``` + +**Diagram sources** +- [src/lib/supabase.js:1-80](file://src/lib/supabase.js#L1-L80) +- [supabase/migrations/001_schema.sql:1-60](file://supabase/migrations/001_schema.sql#L1-L60) +- [src/lib/sync.js:1-80](file://src/lib/sync.js#L1-L80) +- [src/lib/storage.js:1-80](file://src/lib/storage.js#L1-L80) + +**Section sources** +- [src/lib/supabase.js:1-80](file://src/lib/supabase.js#L1-L80) +- [supabase/migrations/001_schema.sql:1-60](file://supabase/migrations/001_schema.sql#L1-L60) +- [src/lib/sync.js:1-80](file://src/lib/sync.js#L1-L80) +- [src/lib/storage.js:1-80](file://src/lib/storage.js#L1-L80) + +### Mobile Support with Capacitor +Capacitor wraps the same React build to produce native iOS/Android apps. Configuration defines app metadata and plugin bridges. + +```mermaid +graph LR +Build["Vite Build Output"] --> Cap["Capacitor Runtime"] +Cap --> Native["Native Shell (iOS/Android)"] +``` + +**Diagram sources** +- [capacitor.config.ts:1-40](file://capacitor.config.ts#L1-L40) + +**Section sources** +- [capacitor.config.ts:1-40](file://capacitor.config.ts#L1-L40) + +### PWA Features +A service worker and web manifest enable caching, offline access, and installability. + +```mermaid +graph TB +Browser["Browser"] --> SW["Service Worker (sw.js)"] +Browser --> Manifest["Web Manifest (manifest.webmanifest)"] +SW --> Cache["Asset Cache"] +Manifest --> Install["Installable App"] +``` + +**Diagram sources** +- [public/sw.js:1-40](file://public/sw.js#L1-L40) +- [public/manifest.webmanifest:1-40](file://public/manifest.webmanifest#L1-L40) + +**Section sources** +- [public/sw.js:1-40](file://public/sw.js#L1-L40) +- [public/manifest.webmanifest:1-40](file://public/manifest.webmanifest#L1-L40) + +## Dependency Analysis +The frontend depends on domain libraries for analysis, scoring, billing, and AI interactions. Serverless functions encapsulate sensitive operations like payment creation and webhook handling. + +```mermaid +graph TB +FE["Frontend (src/*)"] +Libs["Domain Libraries (src/lib/*)"] +Supabase["Supabase DB"] +Funcs["Supabase Functions"] +Payments["PayPal / PayMongo"] +FE --> Libs +Libs --> Supabase +Libs --> Funcs +Funcs --> Payments +``` + +**Diagram sources** +- [src/App.jsx:1-120](file://src/App.jsx#L1-L120) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-80](file://src/lib/entitlement.js#L1-L80) +- [src/lib/ai.js:1-80](file://src/lib/ai.js#L1-L80) +- [supabase/functions/_shared/entitlement.ts:1-80](file://supabase/functions/_shared/entitlement.ts#L1-L80) +- [supabase/functions/_shared/paypal.ts:1-80](file://supabase/functions/_shared/paypal.ts#L1-L80) + +**Section sources** +- [src/App.jsx:1-120](file://src/App.jsx#L1-L120) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [src/lib/entitlement.js:1-80](file://src/lib/entitlement.js#L1-L80) +- [src/lib/ai.js:1-80](file://src/lib/ai.js#L1-L80) +- [supabase/functions/_shared/entitlement.ts:1-80](file://supabase/functions/_shared/entitlement.ts#L1-L80) +- [supabase/functions/_shared/paypal.ts:1-80](file://supabase/functions/_shared/paypal.ts#L1-L80) + +## Performance Considerations +- Prefer lightweight local analysis where possible to reduce AI calls +- Cache AI responses and common prompts to minimize latency +- Use pagination and selective field fetching for large datasets +- Debounce heavy computations (scoring, stats) during rapid updates +- Leverage PWA caching for static assets and frequent reads + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common areas to check: +- Authentication and session issues: verify auth layer initialization and token refresh +- Billing failures: inspect checkout creation logs, capture order steps, and webhook payloads +- AI proxy errors: review error propagation and retry strategies in the proxy function +- Sync conflicts: ensure optimistic updates reconcile with server state +- Mobile build problems: validate Capacitor config and native plugin compatibility + +**Section sources** +- [src/auth.jsx:1-60](file://src/auth.jsx#L1-L60) +- [src/lib/billing.js:1-120](file://src/lib/billing.js#L1-L120) +- [supabase/functions/_shared/http.ts:1-80](file://supabase/functions/_shared/http.ts#L1-L80) +- [supabase/functions/ai-proxy/index.ts:1-80](file://supabase/functions/ai-proxy/index.ts#L1-L80) +- [src/lib/sync.js:1-80](file://src/lib/sync.js#L1-L80) +- [capacitor.config.ts:1-40](file://capacitor.config.ts#L1-L40) + +## Conclusion +ApplyGuard PH delivers a cohesive job search experience by combining robust tracking, AI-powered insights, and flexible billing. Its modular architecture separates concerns between UI, domain logic, and backend services, making it maintainable and extensible. With mobile and PWA support, users can engage with the platform across devices while benefiting from reliable data synchronization and secure payment processing. + +[No sources needed since this section summarizes without analyzing specific files] \ No newline at end of file diff --git a/.qoder/repowiki/en/content/Testing Strategy.md b/.qoder/repowiki/en/content/Testing Strategy.md new file mode 100644 index 0000000..9e4eed7 --- /dev/null +++ b/.qoder/repowiki/en/content/Testing Strategy.md @@ -0,0 +1,367 @@ +# Testing Strategy + + +**Referenced Files in This Document** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [src/lib/csv.test.js](file://src/lib/csv.test.js) +- [src/lib/entitlement.test.js](file://src/lib/entitlement.test.js) +- [src/lib/followups.test.js](file://src/lib/followups.test.js) +- [src/lib/missing.test.js](file://src/lib/missing.test.js) +- [src/lib/redflags.test.js](file://src/lib/redflags.test.js) +- [src/lib/samples.test.js](file://src/lib/samples.test.js) +- [src/lib/scoring.test.js](file://src/lib/scoring.test.js) +- [src/lib/share.test.js](file://src/lib/share.test.js) +- [src/lib/stats.test.js](file://src/lib/stats.test.js) +- [src/lib/sync.test.js](file://src/lib/sync.test.js) +- [supabase/functions/_shared/paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + + +## Table of Contents +1. Introduction +2. Project Structure +3. Core Components +4. Architecture Overview +5. Detailed Component Analysis +6. Dependency Analysis +7. Performance Considerations +8. Troubleshooting Guide +9. Conclusion +10. Appendices + +## Introduction +This document defines the testing strategy for ApplyGuard PH, covering unit tests for business logic, component testing patterns, integration tests for external services, test organization, mocking strategies, continuous integration setup, performance and load testing, end-to-end testing procedures, best practices, code coverage requirements, debugging techniques, tool configuration, and test data management. It is designed to be accessible to both technical and non-technical stakeholders while providing actionable guidance grounded in the repository’s current structure. + +## Project Structure +The project follows a feature-oriented layout with: +- Frontend application under src/, including components, hooks, lib utilities, and entry points. +- Supabase Edge Functions under supabase/functions/ for backend integrations (billing, webhooks, AI proxy). +- Configuration files for build and deployment (package.json, vite.config.js, netlify.toml, vercel.json). +- GitHub Actions workflow under .github/workflows/. +- Existing unit tests colocated next to their modules using the *.test.js convention in src/lib/, and a TypeScript test file in supabase/functions/_shared/paypal.test.ts. + +```mermaid +graph TB +subgraph "Frontend" +A["src/components/*"] +B["src/lib/*.js"] +C["src/hooks/*"] +D["src/main.jsx"] +end +subgraph "Backend (Supabase Edge Functions)" +E["supabase/functions/_shared/*"] +F["supabase/functions/capture-paypal-order/*"] +G["supabase/functions/create-paypal-order/*"] +H["supabase/functions/paymongo-webhook/index.ts"] +I["supabase/functions/paypal-webhook/index.ts"] +J["supabase/functions/ai-proxy/index.ts"] +end +subgraph "Config & CI" +K["package.json"] +L["vite.config.js"] +M[".github/workflows/supabase.yml"] +N["netlify.toml"] +O["vercel.json"] +end +A --> B +C --> B +D --> A +D --> B +E --> F +E --> G +E --> H +E --> I +E --> J +K --> L +M --> E +N --> D +O --> D +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) + +## Core Components +This section outlines the primary areas where testing should focus: +- Business logic libraries under src/lib/: CSV parsing, entitlements, follow-ups, missing items, red flags, samples, scoring, sharing, stats, sync. These are ideal candidates for unit tests due to deterministic inputs/outputs. +- Supabase functions under supabase/functions/_shared/: PayPal helpers and runtime utilities. These integrate with third-party APIs and require careful mocking and contract validation. +- Webhook handlers under supabase/functions/paymongo-webhook/ and paypal-webhook/: Must validate signatures, payloads, and idempotency. +- UI components under src/components/: Should be tested for rendering, user interactions, and state changes via component tests. + +Key responsibilities: +- Unit tests verify pure or isolated logic with deterministic assertions. +- Integration tests validate contracts with external services using mocks or sandbox environments. +- Component tests ensure UI correctness and interaction flows. +- End-to-end tests simulate real user journeys across frontend and backend. + +**Section sources** +- [src/lib/csv.test.js](file://src/lib/csv.test.js) +- [src/lib/entitlement.test.js](file://src/lib/entitlement.test.js) +- [src/lib/followups.test.js](file://src/lib/followups.test.js) +- [src/lib/missing.test.js](file://src/lib/missing.test.js) +- [src/lib/redflags.test.js](file://src/lib/redflags.test.js) +- [src/lib/samples.test.js](file://src/lib/samples.test.js) +- [src/lib/scoring.test.js](file://src/lib/scoring.test.js) +- [src/lib/share.test.js](file://src/lib/share.test.js) +- [src/lib/stats.test.js](file://src/lib/stats.test.js) +- [src/lib/sync.test.js](file://src/lib/sync.test.js) +- [supabase/functions/_shared/paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +## Architecture Overview +Testing architecture aligns with the application layers: +- Unit tests run against src/lib/ modules without network dependencies. +- Integration tests target Supabase Edge Functions with mocked HTTP clients and service stubs. +- Component tests render React components in isolation, simulating events and state updates. +- E2E tests orchestrate full flows from UI to backend endpoints. + +```mermaid +graph TB +UT["Unit Tests
src/lib/*.test.js"] --> Lib["Business Logic
src/lib/*"] +IT["Integration Tests
Edge Functions + Mocks"] --> Func["_shared/*
webhooks/*"] +CT["Component Tests
React Testing Library"] --> Comp["Components
src/components/*"] +E2E["End-to-End Tests
Playwright/Cypress"] --> App["App Entry
src/main.jsx"] +App --> Lib +App --> Comp +Func --> Ext["External Services
PayPal, PayMongo, AI Proxy"] +``` + +[No sources needed since this diagram shows conceptual workflow, not actual code structure] + +## Detailed Component Analysis + +### Unit Testing Strategy for Business Logic +Focus on src/lib/ modules that implement core algorithms and transformations: +- CSV parsing and transformation +- Entitlement checks and pricing calculations +- Follow-up scheduling and reminders +- Missing item detection and recommendations +- Red flag identification rules +- Sample generation and normalization +- Scoring and statistics aggregation +- Sharing/export utilities +- Sync operations and conflict resolution + +Approach: +- Use a lightweight JavaScript test runner compatible with Vite and Node. +- Organize tests alongside source files using the *.test.js naming convention. +- Assert deterministic outputs for given inputs; avoid flaky timing. +- Keep tests fast and isolated; no network calls. + +Best practices: +- Parameterized tests for multiple input scenarios. +- Snapshot tests only when output format is stable and intentional. +- Clear error paths for invalid inputs and edge cases. + +**Section sources** +- [src/lib/csv.test.js](file://src/lib/csv.test.js) +- [src/lib/entitlement.test.js](file://src/lib/entitlement.test.js) +- [src/lib/followups.test.js](file://src/lib/followups.test.js) +- [src/lib/missing.test.js](file://src/lib/missing.test.js) +- [src/lib/redflags.test.js](file://src/lib/redflags.test.js) +- [src/lib/samples.test.js](file://src/lib/samples.test.js) +- [src/lib/scoring.test.js](file://src/lib/scoring.test.js) +- [src/lib/share.test.js](file://src/lib/share.test.js) +- [src/lib/stats.test.js](file://src/lib/stats.test.js) +- [src/lib/sync.test.js](file://src/lib/sync.test.js) + +### Component Testing Patterns +Target React components under src/components/: +- Render minimal UI trees with required props and context. +- Simulate user interactions (clicks, form submissions, navigation). +- Validate state transitions and side effects via spies/stubs. +- Avoid testing implementation details; assert observable behavior. + +Recommendations: +- Use React Testing Library for queries and assertions. +- Mock external dependencies (e.g., storage, analytics, billing) at the module level. +- Keep fixtures small and focused; reuse shared helpers for common setups. + +[No sources needed since this section provides general guidance] + +### Integration Testing for External Services +Focus on Supabase Edge Functions and shared utilities: +- PayPal order creation and capture flows +- Webhook handling for PayMongo and PayPal +- AI proxy routing and request shaping + +Approach: +- Mock HTTP clients used by functions to isolate external calls. +- Validate request/response contracts, headers, and status codes. +- Test webhook signature verification and payload parsing. +- Ensure idempotency and error recovery paths. + +Mocking strategies: +- Replace fetch or HTTP client implementations with test doubles. +- Provide deterministic responses for success, failure, and partial failures. +- Verify retries and backoff behaviors if implemented. + +**Section sources** +- [supabase/functions/_shared/paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) + +### Continuous Integration Setup +Automate testing in CI: +- Run unit and integration tests on every push and pull request. +- Cache dependencies to speed up builds. +- Publish test results and coverage reports. +- Gate merges on passing tests and coverage thresholds. + +Configuration anchors: +- package.json scripts for running tests and coverage. +- Vite configuration for environment variables and test compatibility. +- GitHub Actions workflow for Supabase-related tasks. +- Deployment configs for Netlify and Vercel to ensure consistent environments. + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) +- [netlify.toml](file://netlify.toml) +- [vercel.json](file://vercel.json) + +### Performance Testing, Load Testing, and E2E Procedures +Performance and load testing: +- Identify hotspots in scoring, CSV processing, and sync operations. +- Use benchmarking tools to measure throughput and latency. +- Simulate realistic datasets to validate memory usage and CPU time. + +Load testing: +- Model concurrent users interacting with webhooks and API endpoints. +- Monitor function execution times and error rates under load. +- Tune timeouts and retry policies based on observed metrics. + +End-to-end testing: +- Orchestrate flows from UI submission through backend processing to final outcomes. +- Use browser automation to drive user journeys. +- Isolate E2E runs from production by pointing to staging environments. + +[No sources needed since this section provides general guidance] + +### Best Practices +- Keep tests deterministic and independent. +- Prefer small, focused tests over large monolithic suites. +- Use descriptive names that convey intent and scenario. +- Maintain clear separation between unit, integration, and E2E concerns. +- Regularly review and prune obsolete tests. + +[No sources needed since this section provides general guidance] + +### Code Coverage Requirements +- Set minimum thresholds for line, branch, and function coverage. +- Exclude generated or trivial code from coverage reporting. +- Track coverage trends over time and alert on regressions. +- Require coverage gates in CI pipelines. + +[No sources needed since this section provides general guidance] + +### Debugging Techniques for Failing Tests +- Enable verbose logging and stack traces in test runners. +- Use interactive debugging modes provided by your test framework. +- Isolate failing tests with selective execution flags. +- Capture snapshots or logs around critical sections to diagnose drift. +- Reproduce failures locally with the same environment variables and fixtures. + +[No sources needed since this section provides general guidance] + +### Testing Tools Configuration +- Align test runner with Vite and Node versions defined in package.json. +- Configure environment variables for Supabase and third-party sandboxes. +- Set up coverage reporters and artifact uploads in CI. +- Ensure consistent dependency caching across CI jobs. + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) + +### Test Data Management Strategies +- Centralize fixtures and sample datasets under dedicated directories. +- Version control synthetic data but keep sensitive information out of repositories. +- Use factories or builders to generate varied inputs deterministically. +- Separate test-only data from production seeds. + +[No sources needed since this section provides general guidance] + +## Dependency Analysis +Testing dependencies map closely to application boundaries: +- Unit tests depend only on src/lib/ modules. +- Integration tests depend on Supabase functions and mockable HTTP clients. +- Component tests depend on React Testing Library and minimal app context. +- E2E tests depend on browser automation and staging environments. + +```mermaid +graph TB +Pkg["package.json"] --> VT["vite.config.js"] +VT --> UT["Unit Tests"] +VT --> CT["Component Tests"] +GH["GitHub Actions
.github/workflows/supabase.yml"] --> IT["Integration Tests"] +IT --> SH["_shared/*"] +IT --> WH["Webhooks/*"] +CT --> COMP["Components/*"] +UT --> LIB["Lib/*"] +``` + +**Diagram sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) + +**Section sources** +- [package.json](file://package.json) +- [vite.config.js](file://vite.config.js) +- [.github/workflows/supabase.yml](file://.github/workflows/supabase.yml) + +## Performance Considerations +- Keep unit tests fast by avoiding heavy computations; use smaller datasets. +- Parallelize test execution where possible to reduce CI duration. +- Profile integration tests to identify slow external calls and optimize mocks. +- Monitor memory usage in E2E runs to prevent resource exhaustion. + +[No sources needed since this section provides general guidance] + +## Troubleshooting Guide +Common issues and resolutions: +- Flaky tests caused by timers or randomness: replace with controlled clocks and deterministic seeds. +- Network errors in integration tests: ensure proper mocking and fallback responses. +- Environment variable mismatches: centralize config and validate presence in CI. +- Coverage gaps: add targeted tests for uncovered branches and error paths. + +[No sources needed since this section provides general guidance] + +## Conclusion +ApplyGuard PH’s testing strategy emphasizes fast, reliable unit tests for core logic, robust integration tests for external services, and clear component and E2E procedures. By organizing tests co-located with source files, adopting strong mocking strategies, enforcing coverage thresholds, and automating in CI, the team can maintain high quality and confidence across releases. + +## Appendices + +### Appendix A: Existing Test File Inventory +- src/lib/csv.test.js +- src/lib/entitlement.test.js +- src/lib/followups.test.js +- src/lib/missing.test.js +- src/lib/redflags.test.js +- src/lib/samples.test.js +- src/lib/scoring.test.js +- src/lib/share.test.js +- src/lib/stats.test.js +- src/lib/sync.test.js +- supabase/functions/_shared/paypal.test.ts + +**Section sources** +- [src/lib/csv.test.js](file://src/lib/csv.test.js) +- [src/lib/entitlement.test.js](file://src/lib/entitlement.test.js) +- [src/lib/followups.test.js](file://src/lib/followups.test.js) +- [src/lib/missing.test.js](file://src/lib/missing.test.js) +- [src/lib/redflags.test.js](file://src/lib/redflags.test.js) +- [src/lib/samples.test.js](file://src/lib/samples.test.js) +- [src/lib/scoring.test.js](file://src/lib/scoring.test.js) +- [src/lib/share.test.js](file://src/lib/share.test.js) +- [src/lib/stats.test.js](file://src/lib/stats.test.js) +- [src/lib/sync.test.js](file://src/lib/sync.test.js) +- [supabase/functions/_shared/paypal.test.ts](file://supabase/functions/_shared/paypal.test.ts) \ No newline at end of file diff --git a/.qoder/repowiki/en/meta/repowiki-metadata.json b/.qoder/repowiki/en/meta/repowiki-metadata.json new file mode 100644 index 0000000..7ccf38a --- /dev/null +++ b/.qoder/repowiki/en/meta/repowiki-metadata.json @@ -0,0 +1 @@ +{"knowledge_relations":[{"id":1,"source_id":"b991760f-c629-4fdd-8190-22c10b8cbd73","target_id":"7c87d231-fa5a-4751-9cfd-0722a0e08673","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: b991760f-c629-4fdd-8190-22c10b8cbd73 -\u003e 7c87d231-fa5a-4751-9cfd-0722a0e08673","gmt_create":"2026-07-23T01:50:22.6949598+08:00","gmt_modified":"2026-07-23T01:50:22.6949598+08:00"},{"id":2,"source_id":"7c87d231-fa5a-4751-9cfd-0722a0e08673","target_id":"4caca7e5-6697-4466-b167-68074d08c15a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7c87d231-fa5a-4751-9cfd-0722a0e08673 -\u003e 4caca7e5-6697-4466-b167-68074d08c15a","gmt_create":"2026-07-23T01:50:22.6959982+08:00","gmt_modified":"2026-07-23T01:50:22.6959982+08:00"},{"id":4,"source_id":"f9776e57-edab-4bfd-85e3-6eb9b60a8150","target_id":"6f43f2ce-211e-4561-9ce4-403e8924276a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f9776e57-edab-4bfd-85e3-6eb9b60a8150 -\u003e 6f43f2ce-211e-4561-9ce4-403e8924276a","gmt_create":"2026-07-23T01:50:22.6970593+08:00","gmt_modified":"2026-07-23T01:50:22.6970593+08:00"},{"id":5,"source_id":"abe69d15-cb02-4280-a0ab-ea501393eeba","target_id":"cb931b0f-494b-4342-b2de-d3455bbacbca","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: abe69d15-cb02-4280-a0ab-ea501393eeba -\u003e cb931b0f-494b-4342-b2de-d3455bbacbca","gmt_create":"2026-07-23T01:50:22.6970593+08:00","gmt_modified":"2026-07-23T01:50:22.6970593+08:00"},{"id":6,"source_id":"cb931b0f-494b-4342-b2de-d3455bbacbca","target_id":"a04a71f4-3fbb-45d0-bfee-b10f9dce2e00","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cb931b0f-494b-4342-b2de-d3455bbacbca -\u003e a04a71f4-3fbb-45d0-bfee-b10f9dce2e00","gmt_create":"2026-07-23T01:50:22.697587+08:00","gmt_modified":"2026-07-23T01:50:22.697587+08:00"},{"id":7,"source_id":"cb931b0f-494b-4342-b2de-d3455bbacbca","target_id":"6804acac-8424-4b07-9c5c-39207d1635ce","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cb931b0f-494b-4342-b2de-d3455bbacbca -\u003e 6804acac-8424-4b07-9c5c-39207d1635ce","gmt_create":"2026-07-23T01:50:22.6981182+08:00","gmt_modified":"2026-07-23T01:50:22.6981182+08:00"},{"id":8,"source_id":"cb931b0f-494b-4342-b2de-d3455bbacbca","target_id":"f71247d3-2375-42aa-bbc1-638c1887218d","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cb931b0f-494b-4342-b2de-d3455bbacbca -\u003e f71247d3-2375-42aa-bbc1-638c1887218d","gmt_create":"2026-07-23T01:50:22.6981182+08:00","gmt_modified":"2026-07-23T01:50:22.6981182+08:00"},{"id":9,"source_id":"cb931b0f-494b-4342-b2de-d3455bbacbca","target_id":"25141978-6cab-4672-afe0-db425d50cd9e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cb931b0f-494b-4342-b2de-d3455bbacbca -\u003e 25141978-6cab-4672-afe0-db425d50cd9e","gmt_create":"2026-07-23T01:50:22.6986497+08:00","gmt_modified":"2026-07-23T01:50:22.6986497+08:00"},{"id":10,"source_id":"cb931b0f-494b-4342-b2de-d3455bbacbca","target_id":"055aedc6-d434-4810-b9ca-563cee8b6a89","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: cb931b0f-494b-4342-b2de-d3455bbacbca -\u003e 055aedc6-d434-4810-b9ca-563cee8b6a89","gmt_create":"2026-07-23T01:50:22.6986497+08:00","gmt_modified":"2026-07-23T01:50:22.6986497+08:00"},{"id":11,"source_id":"9caf1b6e-1292-414b-bd72-42b894062757","target_id":"fcfd88e6-c729-4c23-939c-7eb01e39609c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 9caf1b6e-1292-414b-bd72-42b894062757 -\u003e fcfd88e6-c729-4c23-939c-7eb01e39609c","gmt_create":"2026-07-23T01:50:22.6986497+08:00","gmt_modified":"2026-07-23T01:50:22.6986497+08:00"},{"id":12,"source_id":"432424cd-bed4-41ac-9229-4e2dd23f746b","target_id":"130a9db9-c3b8-4d3e-9fa3-2f991a250ca8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 432424cd-bed4-41ac-9229-4e2dd23f746b -\u003e 130a9db9-c3b8-4d3e-9fa3-2f991a250ca8","gmt_create":"2026-07-23T01:50:22.6996589+08:00","gmt_modified":"2026-07-23T01:50:22.6996589+08:00"},{"id":13,"source_id":"130a9db9-c3b8-4d3e-9fa3-2f991a250ca8","target_id":"811ea0a9-3c6e-47f9-b1bd-9d50274b2539","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 130a9db9-c3b8-4d3e-9fa3-2f991a250ca8 -\u003e 811ea0a9-3c6e-47f9-b1bd-9d50274b2539","gmt_create":"2026-07-23T01:50:22.6996589+08:00","gmt_modified":"2026-07-23T01:50:22.6996589+08:00"},{"id":14,"source_id":"130a9db9-c3b8-4d3e-9fa3-2f991a250ca8","target_id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 130a9db9-c3b8-4d3e-9fa3-2f991a250ca8 -\u003e 12d2ce47-ed9f-4d45-ad03-9d6817413345","gmt_create":"2026-07-23T01:50:22.7001671+08:00","gmt_modified":"2026-07-23T01:50:22.7001671+08:00"},{"id":15,"source_id":"130a9db9-c3b8-4d3e-9fa3-2f991a250ca8","target_id":"2f0a73c2-9055-48fd-8b61-a08898ccd82c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 130a9db9-c3b8-4d3e-9fa3-2f991a250ca8 -\u003e 2f0a73c2-9055-48fd-8b61-a08898ccd82c","gmt_create":"2026-07-23T01:50:22.7001671+08:00","gmt_modified":"2026-07-23T01:50:22.7001671+08:00"},{"id":16,"source_id":"ef627730-70d8-4ff3-b3ff-d66e42000bcd","target_id":"dbd0ef0b-894a-472f-bfec-f903ddd1e40d","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ef627730-70d8-4ff3-b3ff-d66e42000bcd -\u003e dbd0ef0b-894a-472f-bfec-f903ddd1e40d","gmt_create":"2026-07-23T01:50:22.7001671+08:00","gmt_modified":"2026-07-23T01:50:22.7001671+08:00"},{"id":17,"source_id":"dbd0ef0b-894a-472f-bfec-f903ddd1e40d","target_id":"cd5c2fbf-88fc-46fd-8efc-0f48452ea130","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dbd0ef0b-894a-472f-bfec-f903ddd1e40d -\u003e cd5c2fbf-88fc-46fd-8efc-0f48452ea130","gmt_create":"2026-07-23T01:50:22.7011722+08:00","gmt_modified":"2026-07-23T01:50:22.7011722+08:00"},{"id":18,"source_id":"dbd0ef0b-894a-472f-bfec-f903ddd1e40d","target_id":"ec6cfe49-fe58-4421-a7ad-beb7c03f52bb","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dbd0ef0b-894a-472f-bfec-f903ddd1e40d -\u003e ec6cfe49-fe58-4421-a7ad-beb7c03f52bb","gmt_create":"2026-07-23T01:50:22.7011722+08:00","gmt_modified":"2026-07-23T01:50:22.7011722+08:00"},{"id":19,"source_id":"dbd0ef0b-894a-472f-bfec-f903ddd1e40d","target_id":"ec9b8bd3-1056-46f6-87b7-8e382a370348","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dbd0ef0b-894a-472f-bfec-f903ddd1e40d -\u003e ec9b8bd3-1056-46f6-87b7-8e382a370348","gmt_create":"2026-07-23T01:50:22.702182+08:00","gmt_modified":"2026-07-23T01:50:22.702182+08:00"},{"id":20,"source_id":"fb00839d-693c-4371-9a3f-30d6e9e87dd8","target_id":"7c8e9f5c-fa29-439d-9861-a403ccd46307","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: fb00839d-693c-4371-9a3f-30d6e9e87dd8 -\u003e 7c8e9f5c-fa29-439d-9861-a403ccd46307","gmt_create":"2026-07-23T01:50:22.702182+08:00","gmt_modified":"2026-07-23T01:50:22.702182+08:00"},{"id":21,"source_id":"7c8e9f5c-fa29-439d-9861-a403ccd46307","target_id":"3917eb63-04bb-43da-bc8c-4e8a12a29740","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7c8e9f5c-fa29-439d-9861-a403ccd46307 -\u003e 3917eb63-04bb-43da-bc8c-4e8a12a29740","gmt_create":"2026-07-23T01:50:22.702182+08:00","gmt_modified":"2026-07-23T01:50:22.702182+08:00"},{"id":22,"source_id":"7c8e9f5c-fa29-439d-9861-a403ccd46307","target_id":"136a9e9e-9db5-414f-9884-abd9f32eec0d","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7c8e9f5c-fa29-439d-9861-a403ccd46307 -\u003e 136a9e9e-9db5-414f-9884-abd9f32eec0d","gmt_create":"2026-07-23T01:50:22.7031821+08:00","gmt_modified":"2026-07-23T01:50:22.7031821+08:00"},{"id":23,"source_id":"7c8e9f5c-fa29-439d-9861-a403ccd46307","target_id":"52d624b9-5360-4bc1-87f6-0ecf5b83ba0e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7c8e9f5c-fa29-439d-9861-a403ccd46307 -\u003e 52d624b9-5360-4bc1-87f6-0ecf5b83ba0e","gmt_create":"2026-07-23T01:50:22.7031821+08:00","gmt_modified":"2026-07-23T01:50:22.7031821+08:00"},{"id":24,"source_id":"7c8e9f5c-fa29-439d-9861-a403ccd46307","target_id":"8653bbaa-86a5-4a06-a72c-a2f1a1e740e9","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7c8e9f5c-fa29-439d-9861-a403ccd46307 -\u003e 8653bbaa-86a5-4a06-a72c-a2f1a1e740e9","gmt_create":"2026-07-23T01:50:22.7031821+08:00","gmt_modified":"2026-07-23T01:50:22.7031821+08:00"},{"id":25,"source_id":"c5ca89d4-889e-4145-891c-29ea1334963e","target_id":"ab8afc85-2c75-408c-ac12-6083bde9eb67","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c5ca89d4-889e-4145-891c-29ea1334963e -\u003e ab8afc85-2c75-408c-ac12-6083bde9eb67","gmt_create":"2026-07-23T01:50:22.7041805+08:00","gmt_modified":"2026-07-23T01:50:22.7041805+08:00"},{"id":26,"source_id":"ab8afc85-2c75-408c-ac12-6083bde9eb67","target_id":"5b3e8598-0e52-4020-9a4b-b82d9222f776","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab8afc85-2c75-408c-ac12-6083bde9eb67 -\u003e 5b3e8598-0e52-4020-9a4b-b82d9222f776","gmt_create":"2026-07-23T01:50:22.7041805+08:00","gmt_modified":"2026-07-23T01:50:22.7041805+08:00"},{"id":27,"source_id":"ab8afc85-2c75-408c-ac12-6083bde9eb67","target_id":"0f515cb7-b028-481b-b603-d4e31d90ae09","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab8afc85-2c75-408c-ac12-6083bde9eb67 -\u003e 0f515cb7-b028-481b-b603-d4e31d90ae09","gmt_create":"2026-07-23T01:50:22.7041805+08:00","gmt_modified":"2026-07-23T01:50:22.7041805+08:00"},{"id":28,"source_id":"ab8afc85-2c75-408c-ac12-6083bde9eb67","target_id":"b1a30f64-960c-451e-ada7-ccff9eba95f6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ab8afc85-2c75-408c-ac12-6083bde9eb67 -\u003e b1a30f64-960c-451e-ada7-ccff9eba95f6","gmt_create":"2026-07-23T01:50:22.7041805+08:00","gmt_modified":"2026-07-23T01:50:22.7041805+08:00"},{"id":29,"source_id":"552f3223-957c-45ce-9b5d-a407be3c0deb","target_id":"a1c38a4d-d97f-4946-8afc-cd684338bf82","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 552f3223-957c-45ce-9b5d-a407be3c0deb -\u003e a1c38a4d-d97f-4946-8afc-cd684338bf82","gmt_create":"2026-07-23T01:50:22.7041805+08:00","gmt_modified":"2026-07-23T01:50:22.7041805+08:00"},{"id":30,"source_id":"ac5d7961-e755-48f5-9339-2773fe90d05c","target_id":"650d90b2-7f26-47a0-b1fc-a57f928538f3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ac5d7961-e755-48f5-9339-2773fe90d05c -\u003e 650d90b2-7f26-47a0-b1fc-a57f928538f3","gmt_create":"2026-07-23T01:50:22.7057671+08:00","gmt_modified":"2026-07-23T01:50:22.7057671+08:00"},{"id":31,"source_id":"650d90b2-7f26-47a0-b1fc-a57f928538f3","target_id":"873168ee-4954-463b-98f0-4bb67adaed30","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 650d90b2-7f26-47a0-b1fc-a57f928538f3 -\u003e 873168ee-4954-463b-98f0-4bb67adaed30","gmt_create":"2026-07-23T01:50:22.7057671+08:00","gmt_modified":"2026-07-23T01:50:22.7057671+08:00"},{"id":32,"source_id":"650d90b2-7f26-47a0-b1fc-a57f928538f3","target_id":"362396ff-4cd6-45c4-b111-571b54d1ff78","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 650d90b2-7f26-47a0-b1fc-a57f928538f3 -\u003e 362396ff-4cd6-45c4-b111-571b54d1ff78","gmt_create":"2026-07-23T01:50:22.7062134+08:00","gmt_modified":"2026-07-23T01:50:22.7062134+08:00"},{"id":33,"source_id":"b991760f-c629-4fdd-8190-22c10b8cbd73","target_id":"813659f7-1f44-4777-8b8b-711d0a7c4034","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: b991760f-c629-4fdd-8190-22c10b8cbd73 -\u003e 813659f7-1f44-4777-8b8b-711d0a7c4034","gmt_create":"2026-07-23T01:50:22.7062134+08:00","gmt_modified":"2026-07-23T01:50:22.7062134+08:00"},{"id":35,"source_id":"f9776e57-edab-4bfd-85e3-6eb9b60a8150","target_id":"7a8dffc7-fba2-4c9c-9701-587d24e2ebfa","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f9776e57-edab-4bfd-85e3-6eb9b60a8150 -\u003e 7a8dffc7-fba2-4c9c-9701-587d24e2ebfa","gmt_create":"2026-07-23T01:50:22.7067677+08:00","gmt_modified":"2026-07-23T01:50:22.7067677+08:00"},{"id":36,"source_id":"9caf1b6e-1292-414b-bd72-42b894062757","target_id":"7f471ec6-418d-4e9e-8a7b-5ff31e821e2e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 9caf1b6e-1292-414b-bd72-42b894062757 -\u003e 7f471ec6-418d-4e9e-8a7b-5ff31e821e2e","gmt_create":"2026-07-23T01:50:22.7078654+08:00","gmt_modified":"2026-07-23T01:50:22.7078654+08:00"},{"id":37,"source_id":"432424cd-bed4-41ac-9229-4e2dd23f746b","target_id":"174da3e3-e8c6-4329-8b6d-114067e34196","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 432424cd-bed4-41ac-9229-4e2dd23f746b -\u003e 174da3e3-e8c6-4329-8b6d-114067e34196","gmt_create":"2026-07-23T01:50:22.7078654+08:00","gmt_modified":"2026-07-23T01:50:22.7078654+08:00"},{"id":38,"source_id":"174da3e3-e8c6-4329-8b6d-114067e34196","target_id":"5d8be249-8b71-4a61-bf4a-efdfe2892d56","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 174da3e3-e8c6-4329-8b6d-114067e34196 -\u003e 5d8be249-8b71-4a61-bf4a-efdfe2892d56","gmt_create":"2026-07-23T01:50:22.7078654+08:00","gmt_modified":"2026-07-23T01:50:22.7078654+08:00"},{"id":39,"source_id":"174da3e3-e8c6-4329-8b6d-114067e34196","target_id":"1c30d26c-5caa-4062-95d8-dc554fd5785a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 174da3e3-e8c6-4329-8b6d-114067e34196 -\u003e 1c30d26c-5caa-4062-95d8-dc554fd5785a","gmt_create":"2026-07-23T01:50:22.7078654+08:00","gmt_modified":"2026-07-23T01:50:22.7078654+08:00"},{"id":40,"source_id":"ef627730-70d8-4ff3-b3ff-d66e42000bcd","target_id":"5e3f5cc1-ce41-4886-b464-457832be2447","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ef627730-70d8-4ff3-b3ff-d66e42000bcd -\u003e 5e3f5cc1-ce41-4886-b464-457832be2447","gmt_create":"2026-07-23T01:50:22.7078654+08:00","gmt_modified":"2026-07-23T01:50:22.7078654+08:00"},{"id":41,"source_id":"5e3f5cc1-ce41-4886-b464-457832be2447","target_id":"d03d56a8-3095-4f9b-9daf-d547a453325e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5e3f5cc1-ce41-4886-b464-457832be2447 -\u003e d03d56a8-3095-4f9b-9daf-d547a453325e","gmt_create":"2026-07-23T01:50:22.7078654+08:00","gmt_modified":"2026-07-23T01:50:22.7078654+08:00"},{"id":42,"source_id":"5e3f5cc1-ce41-4886-b464-457832be2447","target_id":"fec1de01-1e66-442a-a7db-a87e4af03a07","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5e3f5cc1-ce41-4886-b464-457832be2447 -\u003e fec1de01-1e66-442a-a7db-a87e4af03a07","gmt_create":"2026-07-23T01:50:22.7093702+08:00","gmt_modified":"2026-07-23T01:50:22.7093702+08:00"},{"id":43,"source_id":"5e3f5cc1-ce41-4886-b464-457832be2447","target_id":"a5ca0136-be08-4f17-ba3f-662b8fb1112f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5e3f5cc1-ce41-4886-b464-457832be2447 -\u003e a5ca0136-be08-4f17-ba3f-662b8fb1112f","gmt_create":"2026-07-23T01:50:22.7093702+08:00","gmt_modified":"2026-07-23T01:50:22.7093702+08:00"},{"id":44,"source_id":"5e3f5cc1-ce41-4886-b464-457832be2447","target_id":"6b371647-77e3-4cc5-b571-d9a1a488cf4a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5e3f5cc1-ce41-4886-b464-457832be2447 -\u003e 6b371647-77e3-4cc5-b571-d9a1a488cf4a","gmt_create":"2026-07-23T01:50:22.7093702+08:00","gmt_modified":"2026-07-23T01:50:22.7093702+08:00"},{"id":45,"source_id":"fb00839d-693c-4371-9a3f-30d6e9e87dd8","target_id":"dcff2cd0-d56f-4560-ab42-0579c61b6fe0","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: fb00839d-693c-4371-9a3f-30d6e9e87dd8 -\u003e dcff2cd0-d56f-4560-ab42-0579c61b6fe0","gmt_create":"2026-07-23T01:50:22.7103808+08:00","gmt_modified":"2026-07-23T01:50:22.7103808+08:00"},{"id":46,"source_id":"c5ca89d4-889e-4145-891c-29ea1334963e","target_id":"6e8a2261-a4a1-469b-b0cd-ded934fb2502","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c5ca89d4-889e-4145-891c-29ea1334963e -\u003e 6e8a2261-a4a1-469b-b0cd-ded934fb2502","gmt_create":"2026-07-23T01:50:22.7103808+08:00","gmt_modified":"2026-07-23T01:50:22.7103808+08:00"},{"id":47,"source_id":"6e8a2261-a4a1-469b-b0cd-ded934fb2502","target_id":"f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6e8a2261-a4a1-469b-b0cd-ded934fb2502 -\u003e f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","gmt_create":"2026-07-23T01:50:22.7103808+08:00","gmt_modified":"2026-07-23T01:50:22.7103808+08:00"},{"id":48,"source_id":"6e8a2261-a4a1-469b-b0cd-ded934fb2502","target_id":"20d97977-822b-4d02-a223-9b9a9841082f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6e8a2261-a4a1-469b-b0cd-ded934fb2502 -\u003e 20d97977-822b-4d02-a223-9b9a9841082f","gmt_create":"2026-07-23T01:50:22.7114184+08:00","gmt_modified":"2026-07-23T01:50:22.7114184+08:00"},{"id":49,"source_id":"6e8a2261-a4a1-469b-b0cd-ded934fb2502","target_id":"c5b58c7f-08d1-4545-8c9a-af114f1fc6ab","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6e8a2261-a4a1-469b-b0cd-ded934fb2502 -\u003e c5b58c7f-08d1-4545-8c9a-af114f1fc6ab","gmt_create":"2026-07-23T01:50:22.7114184+08:00","gmt_modified":"2026-07-23T01:50:22.7114184+08:00"},{"id":50,"source_id":"552f3223-957c-45ce-9b5d-a407be3c0deb","target_id":"68e10916-bfa4-41d8-b77d-4e84ddc2ccc8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 552f3223-957c-45ce-9b5d-a407be3c0deb -\u003e 68e10916-bfa4-41d8-b77d-4e84ddc2ccc8","gmt_create":"2026-07-23T01:50:22.7114184+08:00","gmt_modified":"2026-07-23T01:50:22.7114184+08:00"},{"id":51,"source_id":"ac5d7961-e755-48f5-9339-2773fe90d05c","target_id":"624e3361-fed5-4347-aedc-d8dc7126f31a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ac5d7961-e755-48f5-9339-2773fe90d05c -\u003e 624e3361-fed5-4347-aedc-d8dc7126f31a","gmt_create":"2026-07-23T01:50:22.7123888+08:00","gmt_modified":"2026-07-23T01:50:22.7123888+08:00"},{"id":52,"source_id":"b991760f-c629-4fdd-8190-22c10b8cbd73","target_id":"6101dd0e-18d5-4021-8513-d52c228e488a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: b991760f-c629-4fdd-8190-22c10b8cbd73 -\u003e 6101dd0e-18d5-4021-8513-d52c228e488a","gmt_create":"2026-07-23T01:50:22.7123888+08:00","gmt_modified":"2026-07-23T01:50:22.7123888+08:00"},{"id":53,"source_id":"abe69d15-cb02-4280-a0ab-ea501393eeba","target_id":"40ab90f4-c71a-4ccc-bd4a-ae19a9de37a3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: abe69d15-cb02-4280-a0ab-ea501393eeba -\u003e 40ab90f4-c71a-4ccc-bd4a-ae19a9de37a3","gmt_create":"2026-07-23T01:50:22.7123888+08:00","gmt_modified":"2026-07-23T01:50:22.7123888+08:00"},{"id":54,"source_id":"f9776e57-edab-4bfd-85e3-6eb9b60a8150","target_id":"fc1625f7-98fe-4301-8072-59f864f7271c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f9776e57-edab-4bfd-85e3-6eb9b60a8150 -\u003e fc1625f7-98fe-4301-8072-59f864f7271c","gmt_create":"2026-07-23T01:50:22.713377+08:00","gmt_modified":"2026-07-23T01:50:22.713377+08:00"},{"id":55,"source_id":"9caf1b6e-1292-414b-bd72-42b894062757","target_id":"f7e89e4b-a8b0-4160-afb8-c76e6d7c38d3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 9caf1b6e-1292-414b-bd72-42b894062757 -\u003e f7e89e4b-a8b0-4160-afb8-c76e6d7c38d3","gmt_create":"2026-07-23T01:50:22.713377+08:00","gmt_modified":"2026-07-23T01:50:22.713377+08:00"},{"id":56,"source_id":"432424cd-bed4-41ac-9229-4e2dd23f746b","target_id":"1c5419db-05c6-40c0-acf3-b6c1ce5b11f8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 432424cd-bed4-41ac-9229-4e2dd23f746b -\u003e 1c5419db-05c6-40c0-acf3-b6c1ce5b11f8","gmt_create":"2026-07-23T01:50:22.713377+08:00","gmt_modified":"2026-07-23T01:50:22.713377+08:00"},{"id":57,"source_id":"fb00839d-693c-4371-9a3f-30d6e9e87dd8","target_id":"c715b8d2-8070-47aa-bfcf-3dee1f30f87c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: fb00839d-693c-4371-9a3f-30d6e9e87dd8 -\u003e c715b8d2-8070-47aa-bfcf-3dee1f30f87c","gmt_create":"2026-07-23T01:50:22.7143773+08:00","gmt_modified":"2026-07-23T01:50:22.7143773+08:00"},{"id":58,"source_id":"ef627730-70d8-4ff3-b3ff-d66e42000bcd","target_id":"c5bab8e6-829c-4015-9586-39d30bfb2302","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ef627730-70d8-4ff3-b3ff-d66e42000bcd -\u003e c5bab8e6-829c-4015-9586-39d30bfb2302","gmt_create":"2026-07-23T01:50:22.7143773+08:00","gmt_modified":"2026-07-23T01:50:22.7143773+08:00"},{"id":59,"source_id":"c5ca89d4-889e-4145-891c-29ea1334963e","target_id":"ee5ed5e8-fb0a-4d24-920b-9e658a00c305","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c5ca89d4-889e-4145-891c-29ea1334963e -\u003e ee5ed5e8-fb0a-4d24-920b-9e658a00c305","gmt_create":"2026-07-23T01:50:22.7143773+08:00","gmt_modified":"2026-07-23T01:50:22.7143773+08:00"},{"id":60,"source_id":"ac5d7961-e755-48f5-9339-2773fe90d05c","target_id":"85253f3a-b62f-4492-a8e2-95f09883b4ee","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ac5d7961-e755-48f5-9339-2773fe90d05c -\u003e 85253f3a-b62f-4492-a8e2-95f09883b4ee","gmt_create":"2026-07-23T01:50:22.715379+08:00","gmt_modified":"2026-07-23T01:50:22.715379+08:00"},{"id":61,"source_id":"552f3223-957c-45ce-9b5d-a407be3c0deb","target_id":"0e6e42c5-2f5b-4cba-ae20-091168e66fa6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 552f3223-957c-45ce-9b5d-a407be3c0deb -\u003e 0e6e42c5-2f5b-4cba-ae20-091168e66fa6","gmt_create":"2026-07-23T01:50:22.715379+08:00","gmt_modified":"2026-07-23T01:50:22.715379+08:00"},{"id":62,"source_id":"9caf1b6e-1292-414b-bd72-42b894062757","target_id":"81caaa05-32a8-49e3-8b93-cce40beed2dd","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 9caf1b6e-1292-414b-bd72-42b894062757 -\u003e 81caaa05-32a8-49e3-8b93-cce40beed2dd","gmt_create":"2026-07-23T01:50:22.715379+08:00","gmt_modified":"2026-07-23T01:50:22.715379+08:00"},{"id":63,"source_id":"b991760f-c629-4fdd-8190-22c10b8cbd73","target_id":"7e04e1fe-9dc6-4f1a-90c4-50032f8042f2","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: b991760f-c629-4fdd-8190-22c10b8cbd73 -\u003e 7e04e1fe-9dc6-4f1a-90c4-50032f8042f2","gmt_create":"2026-07-23T01:50:22.715379+08:00","gmt_modified":"2026-07-23T01:50:22.715379+08:00"},{"id":64,"source_id":"c5ca89d4-889e-4145-891c-29ea1334963e","target_id":"0ed0995a-fa23-445d-90cb-82e1b8b90368","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c5ca89d4-889e-4145-891c-29ea1334963e -\u003e 0ed0995a-fa23-445d-90cb-82e1b8b90368","gmt_create":"2026-07-23T01:50:22.7164999+08:00","gmt_modified":"2026-07-23T01:50:22.7164999+08:00"},{"id":65,"source_id":"ac5d7961-e755-48f5-9339-2773fe90d05c","target_id":"fd7c30f1-7245-4209-9df9-831da20bb681","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ac5d7961-e755-48f5-9339-2773fe90d05c -\u003e fd7c30f1-7245-4209-9df9-831da20bb681","gmt_create":"2026-07-23T01:50:22.7164999+08:00","gmt_modified":"2026-07-23T01:50:22.7164999+08:00"},{"id":66,"source_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","target_id":"d8071b4e-e992-45dd-b490-b0d1b589d98f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: e1688bba-ce2d-44bf-8cd9-7b80e2135cb5 -\u003e d8071b4e-e992-45dd-b490-b0d1b589d98f","gmt_create":"2026-07-23T01:50:22.7164999+08:00","gmt_modified":"2026-07-23T01:50:22.7164999+08:00"},{"id":67,"source_id":"f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","target_id":"bf7bcf00-6bc8-4011-856d-9599db635e61","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc -\u003e bf7bcf00-6bc8-4011-856d-9599db635e61","gmt_create":"2026-07-23T01:50:22.7175056+08:00","gmt_modified":"2026-07-23T01:50:22.7175056+08:00"},{"id":68,"source_id":"f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","target_id":"8fe13cfb-970c-4495-9237-a7c099313dc2","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc -\u003e 8fe13cfb-970c-4495-9237-a7c099313dc2","gmt_create":"2026-07-23T01:50:22.7175056+08:00","gmt_modified":"2026-07-23T01:50:22.7175056+08:00"},{"id":69,"source_id":"f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","target_id":"580b1cad-169f-492a-9808-b6e50a73bb17","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc -\u003e 580b1cad-169f-492a-9808-b6e50a73bb17","gmt_create":"2026-07-23T01:50:22.7185146+08:00","gmt_modified":"2026-07-23T01:50:22.7185146+08:00"},{"id":70,"source_id":"f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","target_id":"fe8a23cd-6ffb-44f0-92bf-2ceb833275c7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc -\u003e fe8a23cd-6ffb-44f0-92bf-2ceb833275c7","gmt_create":"2026-07-23T01:50:22.7185146+08:00","gmt_modified":"2026-07-23T01:50:22.7185146+08:00"},{"id":71,"source_id":"75717c15-f820-47b2-b1bc-d301569048f6","target_id":"2cb527c6-096c-4f04-99ba-ca50b7f02c3f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 75717c15-f820-47b2-b1bc-d301569048f6 -\u003e 2cb527c6-096c-4f04-99ba-ca50b7f02c3f","gmt_create":"2026-07-23T01:50:22.7185146+08:00","gmt_modified":"2026-07-23T01:50:22.7185146+08:00"},{"id":72,"source_id":"5b3e8598-0e52-4020-9a4b-b82d9222f776","target_id":"d93643a2-8666-47a6-95b9-2efe789c71c9","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5b3e8598-0e52-4020-9a4b-b82d9222f776 -\u003e d93643a2-8666-47a6-95b9-2efe789c71c9","gmt_create":"2026-07-23T01:50:22.7195143+08:00","gmt_modified":"2026-07-23T01:50:22.7195143+08:00"},{"id":73,"source_id":"5b3e8598-0e52-4020-9a4b-b82d9222f776","target_id":"ad9531d9-601e-4dde-844f-6b1994675fd9","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5b3e8598-0e52-4020-9a4b-b82d9222f776 -\u003e ad9531d9-601e-4dde-844f-6b1994675fd9","gmt_create":"2026-07-23T01:50:22.7195143+08:00","gmt_modified":"2026-07-23T01:50:22.7195143+08:00"},{"id":74,"source_id":"5b3e8598-0e52-4020-9a4b-b82d9222f776","target_id":"47d11b23-33b3-40a7-9ec6-e17143543335","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5b3e8598-0e52-4020-9a4b-b82d9222f776 -\u003e 47d11b23-33b3-40a7-9ec6-e17143543335","gmt_create":"2026-07-23T01:50:22.7195143+08:00","gmt_modified":"2026-07-23T01:50:22.7195143+08:00"},{"id":75,"source_id":"5b3e8598-0e52-4020-9a4b-b82d9222f776","target_id":"2dd63aa4-8560-409c-bf54-377ba4d036a4","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 5b3e8598-0e52-4020-9a4b-b82d9222f776 -\u003e 2dd63aa4-8560-409c-bf54-377ba4d036a4","gmt_create":"2026-07-23T01:50:22.720581+08:00","gmt_modified":"2026-07-23T01:50:22.720581+08:00"},{"id":76,"source_id":"0a752f6c-297a-43d7-85b3-d45c13850d0b","target_id":"d37f0e06-479e-4598-8fd6-0d546d548831","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 0a752f6c-297a-43d7-85b3-d45c13850d0b -\u003e d37f0e06-479e-4598-8fd6-0d546d548831","gmt_create":"2026-07-23T01:50:22.720581+08:00","gmt_modified":"2026-07-23T01:50:22.720581+08:00"},{"id":77,"source_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","target_id":"06ce0d34-6e01-45ad-879e-b669d78b657f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: e1688bba-ce2d-44bf-8cd9-7b80e2135cb5 -\u003e 06ce0d34-6e01-45ad-879e-b669d78b657f","gmt_create":"2026-07-23T01:50:22.7215807+08:00","gmt_modified":"2026-07-23T01:50:22.7215807+08:00"},{"id":78,"source_id":"75717c15-f820-47b2-b1bc-d301569048f6","target_id":"0b3cf703-787d-4d5b-9b09-f6e8a99e8725","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 75717c15-f820-47b2-b1bc-d301569048f6 -\u003e 0b3cf703-787d-4d5b-9b09-f6e8a99e8725","gmt_create":"2026-07-23T01:50:22.7225805+08:00","gmt_modified":"2026-07-23T01:50:22.7225805+08:00"},{"id":79,"source_id":"0a752f6c-297a-43d7-85b3-d45c13850d0b","target_id":"a264ffd0-6923-45e0-8ba7-15fd7c2ca396","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 0a752f6c-297a-43d7-85b3-d45c13850d0b -\u003e a264ffd0-6923-45e0-8ba7-15fd7c2ca396","gmt_create":"2026-07-23T01:50:22.7235792+08:00","gmt_modified":"2026-07-23T01:50:22.7235792+08:00"},{"id":80,"source_id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","target_id":"ae7cb597-7377-4c4a-9ccf-7177a1297172","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 12d2ce47-ed9f-4d45-ad03-9d6817413345 -\u003e ae7cb597-7377-4c4a-9ccf-7177a1297172","gmt_create":"2026-07-23T01:50:22.7235792+08:00","gmt_modified":"2026-07-23T01:50:22.7235792+08:00"},{"id":81,"source_id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","target_id":"777ae6e8-f1f4-46da-9f7a-a9209d4fb4ae","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 12d2ce47-ed9f-4d45-ad03-9d6817413345 -\u003e 777ae6e8-f1f4-46da-9f7a-a9209d4fb4ae","gmt_create":"2026-07-23T01:50:22.7245901+08:00","gmt_modified":"2026-07-23T01:50:22.7245901+08:00"},{"id":82,"source_id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","target_id":"c5c8e666-fb3e-4430-8e6f-2fde0f429319","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 12d2ce47-ed9f-4d45-ad03-9d6817413345 -\u003e c5c8e666-fb3e-4430-8e6f-2fde0f429319","gmt_create":"2026-07-23T01:50:22.7245901+08:00","gmt_modified":"2026-07-23T01:50:22.7245901+08:00"},{"id":83,"source_id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","target_id":"babb38b4-3464-43f8-af32-4c89ce235e8a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 12d2ce47-ed9f-4d45-ad03-9d6817413345 -\u003e babb38b4-3464-43f8-af32-4c89ce235e8a","gmt_create":"2026-07-23T01:50:22.7245901+08:00","gmt_modified":"2026-07-23T01:50:22.7245901+08:00"},{"id":84,"source_id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","target_id":"2934e026-a0ec-46ed-84ea-c153dfd41808","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 12d2ce47-ed9f-4d45-ad03-9d6817413345 -\u003e 2934e026-a0ec-46ed-84ea-c153dfd41808","gmt_create":"2026-07-23T01:50:22.7255854+08:00","gmt_modified":"2026-07-23T01:50:22.7255854+08:00"},{"id":85,"source_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","target_id":"6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: e1688bba-ce2d-44bf-8cd9-7b80e2135cb5 -\u003e 6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e","gmt_create":"2026-07-23T01:50:22.7255854+08:00","gmt_modified":"2026-07-23T01:50:22.7255854+08:00"},{"id":86,"source_id":"6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e","target_id":"8bda8974-4c19-4f3d-aa33-3a0f9401d50f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e -\u003e 8bda8974-4c19-4f3d-aa33-3a0f9401d50f","gmt_create":"2026-07-23T01:50:22.7255854+08:00","gmt_modified":"2026-07-23T01:50:22.7255854+08:00"},{"id":87,"source_id":"6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e","target_id":"e0adec41-36a7-4997-9d39-62ebd8e126bb","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e -\u003e e0adec41-36a7-4997-9d39-62ebd8e126bb","gmt_create":"2026-07-23T01:50:22.7265818+08:00","gmt_modified":"2026-07-23T01:50:22.7265818+08:00"},{"id":88,"source_id":"75717c15-f820-47b2-b1bc-d301569048f6","target_id":"bd64e7d8-0cb1-4e28-8485-d2b67e758171","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 75717c15-f820-47b2-b1bc-d301569048f6 -\u003e bd64e7d8-0cb1-4e28-8485-d2b67e758171","gmt_create":"2026-07-23T01:50:22.7265818+08:00","gmt_modified":"2026-07-23T01:50:22.7265818+08:00"},{"id":89,"source_id":"0a752f6c-297a-43d7-85b3-d45c13850d0b","target_id":"12a298c9-3ac0-49b7-bac3-a8aceb5fd341","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 0a752f6c-297a-43d7-85b3-d45c13850d0b -\u003e 12a298c9-3ac0-49b7-bac3-a8aceb5fd341","gmt_create":"2026-07-23T01:50:22.7275918+08:00","gmt_modified":"2026-07-23T01:50:22.7275918+08:00"},{"id":90,"source_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","target_id":"7a38bc59-3f8e-4a91-9b8d-ee3ca0e4eff7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: e1688bba-ce2d-44bf-8cd9-7b80e2135cb5 -\u003e 7a38bc59-3f8e-4a91-9b8d-ee3ca0e4eff7","gmt_create":"2026-07-23T01:50:22.7275918+08:00","gmt_modified":"2026-07-23T01:50:22.7275918+08:00"},{"id":91,"source_id":"75717c15-f820-47b2-b1bc-d301569048f6","target_id":"fca2cf7c-9bb9-44cd-a6ff-ff332c848066","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 75717c15-f820-47b2-b1bc-d301569048f6 -\u003e fca2cf7c-9bb9-44cd-a6ff-ff332c848066","gmt_create":"2026-07-23T01:50:22.7285853+08:00","gmt_modified":"2026-07-23T01:50:22.7285853+08:00"},{"id":92,"source_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","target_id":"c3dd5c76-9353-4573-a4cc-9d1b73474c77","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: e1688bba-ce2d-44bf-8cd9-7b80e2135cb5 -\u003e c3dd5c76-9353-4573-a4cc-9d1b73474c77","gmt_create":"2026-07-23T01:50:22.7285853+08:00","gmt_modified":"2026-07-23T01:50:22.7285853+08:00"},{"id":93,"source_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","target_id":"244a7635-aee7-4997-8bde-8650e0258fa2","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: e1688bba-ce2d-44bf-8cd9-7b80e2135cb5 -\u003e 244a7635-aee7-4997-8bde-8650e0258fa2","gmt_create":"2026-07-23T01:50:22.7285853+08:00","gmt_modified":"2026-07-23T01:50:22.7285853+08:00"},{"id":94,"source_id":"8fe13cfb-970c-4495-9237-a7c099313dc2","target_id":"1ca86cc8-2fe2-4d9f-996b-b04ec4cc7550","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 8fe13cfb-970c-4495-9237-a7c099313dc2 -\u003e 1ca86cc8-2fe2-4d9f-996b-b04ec4cc7550","gmt_create":"2026-07-23T01:50:22.7300903+08:00","gmt_modified":"2026-07-23T01:50:22.7300903+08:00"},{"id":95,"source_id":"8fe13cfb-970c-4495-9237-a7c099313dc2","target_id":"a274eebc-f1f4-443b-80a3-1d7ee0148007","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 8fe13cfb-970c-4495-9237-a7c099313dc2 -\u003e a274eebc-f1f4-443b-80a3-1d7ee0148007","gmt_create":"2026-07-23T01:50:22.7300903+08:00","gmt_modified":"2026-07-23T01:50:22.7300903+08:00"},{"id":96,"source_id":"8fe13cfb-970c-4495-9237-a7c099313dc2","target_id":"6955aa54-5599-4834-87e3-cbb200ecefc7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 8fe13cfb-970c-4495-9237-a7c099313dc2 -\u003e 6955aa54-5599-4834-87e3-cbb200ecefc7","gmt_create":"2026-07-23T01:50:22.7300903+08:00","gmt_modified":"2026-07-23T01:50:22.7300903+08:00"},{"id":97,"source_id":"fb00839d-693c-4371-9a3f-30d6e9e87dd8","target_id":"75717c15-f820-47b2-b1bc-d301569048f6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: fb00839d-693c-4371-9a3f-30d6e9e87dd8 -\u003e 75717c15-f820-47b2-b1bc-d301569048f6","gmt_create":"2026-07-23T01:50:22.7320946+08:00","gmt_modified":"2026-07-23T01:50:22.7320946+08:00"},{"id":98,"source_id":"ef627730-70d8-4ff3-b3ff-d66e42000bcd","target_id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ef627730-70d8-4ff3-b3ff-d66e42000bcd -\u003e e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","gmt_create":"2026-07-23T01:50:22.7320946+08:00","gmt_modified":"2026-07-23T01:50:22.7320946+08:00"},{"id":99,"source_id":"c5ca89d4-889e-4145-891c-29ea1334963e","target_id":"e5dc03c8-ce96-427d-8590-dac8fc2a769e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c5ca89d4-889e-4145-891c-29ea1334963e -\u003e e5dc03c8-ce96-427d-8590-dac8fc2a769e","gmt_create":"2026-07-23T01:50:22.7335969+08:00","gmt_modified":"2026-07-23T01:50:22.7335969+08:00"},{"id":100,"source_id":"ac5d7961-e755-48f5-9339-2773fe90d05c","target_id":"0a752f6c-297a-43d7-85b3-d45c13850d0b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ac5d7961-e755-48f5-9339-2773fe90d05c -\u003e 0a752f6c-297a-43d7-85b3-d45c13850d0b","gmt_create":"2026-07-23T01:50:22.7335969+08:00","gmt_modified":"2026-07-23T01:50:22.7335969+08:00"},{"id":101,"source_id":"552f3223-957c-45ce-9b5d-a407be3c0deb","target_id":"00d944ce-ee63-417b-8e53-dbe2ea6c7362","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 552f3223-957c-45ce-9b5d-a407be3c0deb -\u003e 00d944ce-ee63-417b-8e53-dbe2ea6c7362","gmt_create":"2026-07-23T01:50:22.7346021+08:00","gmt_modified":"2026-07-23T01:50:22.7346021+08:00"},{"id":102,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"74d14aa87805d337adca33cdd52b4d69","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/_shared/paypal.ts","gmt_create":"2026-07-23T02:10:29.6961163+08:00","gmt_modified":"2026-07-23T02:10:29.6961163+08:00"},{"id":103,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"ececb4f4d4a5b5a3b60f37b2207b9ea0","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/_shared/paypal-runtime.ts","gmt_create":"2026-07-23T02:10:29.6966514+08:00","gmt_modified":"2026-07-23T02:10:29.6966514+08:00"},{"id":104,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"ef3ccb6435a8ed6d7a1308574dcbc18d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/_shared/paypal.test.ts","gmt_create":"2026-07-23T02:10:29.6966514+08:00","gmt_modified":"2026-07-23T02:10:29.6966514+08:00"},{"id":105,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"a87b2919e99b4ba9f39a25800395616e","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/create-paypal-order/index.ts","gmt_create":"2026-07-23T02:10:29.6971897+08:00","gmt_modified":"2026-07-23T02:10:29.6971897+08:00"},{"id":106,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"2345f19a189e55a76fc6186fad344ec4","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/capture-paypal-order/index.ts","gmt_create":"2026-07-23T02:10:29.6977217+08:00","gmt_modified":"2026-07-23T02:10:29.6977217+08:00"},{"id":107,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"4e4ca50f152e023e4cd79ff4ed3b6492","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/paypal-webhook/index.ts","gmt_create":"2026-07-23T02:10:29.6977217+08:00","gmt_modified":"2026-07-23T02:10:29.6977217+08:00"},{"id":108,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"fd6440b9fcd1c2ac06534edf1f584114","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T02:10:29.6982451+08:00","gmt_modified":"2026-07-23T02:10:29.6982451+08:00"},{"id":109,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"f854f01c88f83a5b676e346230234c87","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/migrations/002_paypal_fulfillment.sql","gmt_create":"2026-07-23T02:10:29.6982451+08:00","gmt_modified":"2026-07-23T02:10:29.6982451+08:00"},{"id":110,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"48881c9ddc2be14caf03d54f63202a1d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: src/lib/billing.js","gmt_create":"2026-07-23T02:10:29.6987778+08:00","gmt_modified":"2026-07-23T02:10:29.6987778+08:00"},{"id":111,"source_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","target_id":"13cd63fad68b852b2abd9eb4b040aaec","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/_shared/entitlement.ts","gmt_create":"2026-07-23T02:10:29.6992843+08:00","gmt_modified":"2026-07-23T02:10:29.6992843+08:00"},{"id":112,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"44fca811610d4d2cc2328f38cfdd5954","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/config.toml","gmt_create":"2026-07-23T02:10:32.1807609+08:00","gmt_modified":"2026-07-23T02:10:32.1807609+08:00"},{"id":113,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"493a7230a7e5acc82a0601c7d31631f7","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/migrations/001_schema.sql","gmt_create":"2026-07-23T02:10:32.1812897+08:00","gmt_modified":"2026-07-23T02:10:32.1812897+08:00"},{"id":114,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"f854f01c88f83a5b676e346230234c87","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/migrations/002_paypal_fulfillment.sql","gmt_create":"2026-07-23T02:10:32.1825074+08:00","gmt_modified":"2026-07-23T02:10:32.1825074+08:00"},{"id":115,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"a370ec23c4b21fc6263758df0d54e384","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: src/lib/supabase.js","gmt_create":"2026-07-23T02:10:32.1830136+08:00","gmt_modified":"2026-07-23T02:10:32.1830136+08:00"},{"id":116,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"48881c9ddc2be14caf03d54f63202a1d","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: src/lib/billing.js","gmt_create":"2026-07-23T02:10:32.1830136+08:00","gmt_modified":"2026-07-23T02:10:32.1830136+08:00"},{"id":117,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"865c4d1d26b4360b1b802c0d5171c7c5","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: src/lib/entitlement.js","gmt_create":"2026-07-23T02:10:32.1835444+08:00","gmt_modified":"2026-07-23T02:10:32.1835444+08:00"},{"id":118,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"13cd63fad68b852b2abd9eb4b040aaec","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/_shared/entitlement.ts","gmt_create":"2026-07-23T02:10:32.1840678+08:00","gmt_modified":"2026-07-23T02:10:32.1840678+08:00"},{"id":119,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"b30cccd4f349d7e770956ff9d8381035","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/paymongo-webhook/index.ts","gmt_create":"2026-07-23T02:10:32.1844733+08:00","gmt_modified":"2026-07-23T02:10:32.1844733+08:00"},{"id":120,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"4e4ca50f152e023e4cd79ff4ed3b6492","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/paypal-webhook/index.ts","gmt_create":"2026-07-23T02:10:32.1849812+08:00","gmt_modified":"2026-07-23T02:10:32.1849812+08:00"},{"id":121,"source_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","target_id":"fd6440b9fcd1c2ac06534edf1f584114","source_type":"WIKI_ITEM","target_type":"SOURCE_FILE","relationship_type":"REFERENCED_BY","extra":"Wiki references source file: supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T02:10:32.185517+08:00","gmt_modified":"2026-07-23T02:10:32.185517+08:00"},{"id":122,"source_id":"7c87d231-fa5a-4751-9cfd-0722a0e08673","target_id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7c87d231-fa5a-4751-9cfd-0722a0e08673 -\u003e 1addd91a-7bb1-4d30-8890-34caadd3a86b","gmt_create":"2026-07-23T02:11:09.84571+08:00","gmt_modified":"2026-07-23T02:11:09.84571+08:00"},{"id":123,"source_id":"abe69d15-cb02-4280-a0ab-ea501393eeba","target_id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: abe69d15-cb02-4280-a0ab-ea501393eeba -\u003e a2664f5c-317d-48ec-aaa2-3721c4918e94","gmt_create":"2026-07-23T02:11:09.8534944+08:00","gmt_modified":"2026-07-23T02:11:09.8534944+08:00"},{"id":124,"source_id":"b991760f-c629-4fdd-8190-22c10b8cbd73","target_id":"44f8e3aa-0a7f-4ce0-939e-e57818c51674","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: b991760f-c629-4fdd-8190-22c10b8cbd73 -\u003e 44f8e3aa-0a7f-4ce0-939e-e57818c51674","gmt_create":"2026-07-23T02:11:09.8897802+08:00","gmt_modified":"2026-07-23T02:11:09.8897802+08:00"}],"source_files":[{"id":"74d14aa87805d337adca33cdd52b4d69","path":"supabase/functions/_shared/paypal.ts","filename":"paypal.ts","gmt_create":"2026-07-23T02:10:29.6950587+08:00","gmt_modified":"2026-07-23T02:10:29.6950587+08:00"},{"id":"ececb4f4d4a5b5a3b60f37b2207b9ea0","path":"supabase/functions/_shared/paypal-runtime.ts","filename":"paypal-runtime.ts","gmt_create":"2026-07-23T02:10:29.6950587+08:00","gmt_modified":"2026-07-23T02:10:29.6950587+08:00"},{"id":"ef3ccb6435a8ed6d7a1308574dcbc18d","path":"supabase/functions/_shared/paypal.test.ts","filename":"paypal.test.ts","gmt_create":"2026-07-23T02:10:29.6955914+08:00","gmt_modified":"2026-07-23T02:10:29.6955914+08:00"},{"id":"a87b2919e99b4ba9f39a25800395616e","path":"supabase/functions/create-paypal-order/index.ts","filename":"index.ts","gmt_create":"2026-07-23T02:10:29.6955914+08:00","gmt_modified":"2026-07-23T02:10:29.6955914+08:00"},{"id":"2345f19a189e55a76fc6186fad344ec4","path":"supabase/functions/capture-paypal-order/index.ts","filename":"index.ts","gmt_create":"2026-07-23T02:10:29.6955914+08:00","gmt_modified":"2026-07-23T02:10:29.6955914+08:00"},{"id":"4e4ca50f152e023e4cd79ff4ed3b6492","path":"supabase/functions/paypal-webhook/index.ts","filename":"index.ts","gmt_create":"2026-07-23T02:10:29.6955914+08:00","gmt_modified":"2026-07-23T02:10:29.6955914+08:00"},{"id":"fd6440b9fcd1c2ac06534edf1f584114","path":"supabase/functions/cancel-subscription/index.ts","filename":"index.ts","gmt_create":"2026-07-23T02:10:29.6955914+08:00","gmt_modified":"2026-07-23T02:10:29.6955914+08:00"},{"id":"f854f01c88f83a5b676e346230234c87","path":"supabase/migrations/002_paypal_fulfillment.sql","filename":"002_paypal_fulfillment.sql","gmt_create":"2026-07-23T02:10:29.6955914+08:00","gmt_modified":"2026-07-23T02:10:29.6955914+08:00"},{"id":"48881c9ddc2be14caf03d54f63202a1d","path":"src/lib/billing.js","filename":"billing.js","gmt_create":"2026-07-23T02:10:29.6961163+08:00","gmt_modified":"2026-07-23T02:10:29.6961163+08:00"},{"id":"13cd63fad68b852b2abd9eb4b040aaec","path":"supabase/functions/_shared/entitlement.ts","filename":"entitlement.ts","gmt_create":"2026-07-23T02:10:29.6961163+08:00","gmt_modified":"2026-07-23T02:10:29.6961163+08:00"},{"id":"44fca811610d4d2cc2328f38cfdd5954","path":"supabase/config.toml","filename":"config.toml","gmt_create":"2026-07-23T02:10:32.1786531+08:00","gmt_modified":"2026-07-23T02:10:32.1786531+08:00"},{"id":"493a7230a7e5acc82a0601c7d31631f7","path":"supabase/migrations/001_schema.sql","filename":"001_schema.sql","gmt_create":"2026-07-23T02:10:32.1791706+08:00","gmt_modified":"2026-07-23T02:10:32.1791706+08:00"},{"id":"a370ec23c4b21fc6263758df0d54e384","path":"src/lib/supabase.js","filename":"supabase.js","gmt_create":"2026-07-23T02:10:32.1796897+08:00","gmt_modified":"2026-07-23T02:10:32.1796897+08:00"},{"id":"865c4d1d26b4360b1b802c0d5171c7c5","path":"src/lib/entitlement.js","filename":"entitlement.js","gmt_create":"2026-07-23T02:10:32.1796897+08:00","gmt_modified":"2026-07-23T02:10:32.1796897+08:00"},{"id":"b30cccd4f349d7e770956ff9d8381035","path":"supabase/functions/paymongo-webhook/index.ts","filename":"index.ts","gmt_create":"2026-07-23T02:10:32.1802259+08:00","gmt_modified":"2026-07-23T02:10:32.1802259+08:00"}],"wiki_catalogs":[{"id":"a62c01b7-2292-49d3-80b8-d7616a455c58","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Project Overview","description":"project-overview","prompt":"Create comprehensive content for the ApplyGuard PH project overview section. Explain its purpose as a job application tracking and analysis platform with AI-powered features, core value proposition, and key benefits for job seekers. Document the technology stack including React frontend, Supabase backend, Capacitor mobile support, and payment integrations. Provide an architectural overview showing how components interact and data flows through the system. Include screenshots or descriptions of main features like resume scanning, interview preparation, offer management, and subscription billing. Address the target audience and use cases. Make content accessible to both technical and non-technical readers while establishing the foundation for deeper technical documentation.","progress_status":"completed","dependent_files":"README.md,package.json,index.html,src/App.jsx","gmt_create":"2026-07-23T01:21:36.3281149+08:00","gmt_modified":"2026-07-23T01:45:39.6328312+08:00","raw_data":"WikiEncrypted:0MI1/XkBoMl0lTbK6t0Cn/+8FdvqrJ62ianMLvZj02dqzTho5arqNtbUziutSzUZOqm7yOpCxfwhmmzZqG/lBD3pMVXunyKmPUgiOnGRUOBaiu4NoJ2bqNizKafQrY+yMxLbWiy+Rp0cjDgUXjCoCdWxwENAm/XBsIWpU1cYEWPj3j/r7I9E+S0/aWxboTuurBTePCln+xavCt9D+FF8W5qaiwrRiNFL8rheP+MI1TRIMo8ik22dljS2xOrvxTG+tl2T/9uhJl3oJzOqr4MxP+klDeWINvLXXAEWSSt/4ml03827mA5m0B+MK/ZdUJC/BAEIuqgQB/Puzwo91/B+ujiXzfZNSUvzpuEP7BW+N+z7U39bqYiuDm12mGlm01DLtmMSRrIy/wSJf1hXwbI0IM2Q/6jxw/b7IqBYPjP6o2gbFiIMHl1pPisJL2ZwsqG6oguXsR9NC5WKRXuqAmAVYrt9fg28xfnQX1q5AOY/mKisPMnJkMsA8BoPBoWjR5ZRYqaLWhlPHWkV4UT/nCE85Ve+aJ4EUS1pd/CeCsJI86s55+q5W9uY5DQL/dIo5wjhvtVUE0awFEtW61b9rgqbpTHQ9klSM76SmiMAB10pHrGegfBeutwbgQIcuNSHEW02aV6Cbhy2xVaRK54ls92h8H2vrrWFjfaKlmOmqEXRLQJvslHi+ro8RS2bwZyUQu27d6uw/oF5IVHtufSNhHQm0RQt9VYdEq+IK1POsOx8Sy9e3drsffmJu+epLkGEnPqzC5p2N5YW6fXfquXcRkpPXGoVDYN5jVIujQZNj6ULw4o2MAbU3BU3crYFVjQ/e/lZOlYcuysR0Jw+tPtu5G+9sUu7g8hp5exfqLhJw3i37MAD+9XlkChaYM48T7T11KEAY27T9K2BAUrwX4HVC5jsheZZqP0gMxvolhmrYK28jFihYQ6EwKSAG1IrYWhZRB7+kd3hWXCHnTTxjbj906aLlVsP9l/q2B/URJuH8KxUJXu4KdYIk+X8em18Ts7Bj0+OQ8kAY3R6OsnwUXJmCHuV17w0Pvm+JXPycc/PHApXPI2PAv1JmTArJ3gRqN6xc0Z29HEsXDn5xPrV91BVBfijDRCnqiQCuaQ36UB/nfHDajD1C8V2TsIDyM2Sy1GLG1Sxki0xXsSPIe9cclbqK2OMQTPZkQfgIsBcFIe2v5RU1y1cX+f1vGHI9YBhvIf5w3Dtpgd1eXuDOA5XSB2lpsiicPH03NpX6NL+XY2kphwnjEAjICuz4ITVU55eaiLzdNBlgQgXq9MdVcsuTxtYw5pzwiT9iL28Qzo01guxVkH4RqLLzh5TYEh1WYemhHf5sUYJW8uI73JbDwjgxZv6S2p43Bu5G8gSmsBBXbrTfcQPGRpicyNTb1nV3rRMRzTuDaTP9+FLX/0M9ZmHHhbIPpraj/HfdaAguhoMOYJp8/YGS242+4PF4/1ZCkBadcO3TMjx8cVO5eCLJnnRciP8sL9286qH95JhTwlV2gjDyIMrx8Sq/TyYLHJgn2EuyiPDUKuSYIoytNDkFiGieDhDgHoG4byQIarxRToVoUxigdhpifvCYyDNG/RsPCLTPHsLehfYxINuS/lmM0SPkKCp99kpSyvgRKGRlJ78nZD2pWxZw56KkZe1GBIAPBHCxDhhECcaClEv6aBhoexHGeb+m564GQ=="},{"id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Job Application Tracker","description":"job-application-tracker","prompt":"Create comprehensive documentation for the Job Application Tracker feature. Document the tracker dashboard interface, application management workflows, status tracking system, and follow-up automation. Explain how users can add, edit, and organize job applications, track application statuses, and manage follow-up tasks. Detail the statistics and analytics capabilities, next action suggestions, and data visualization features. Include examples of common usage patterns, custom fields configuration, and integration with other features like AI analysis and offer comparison.","parent_id":"564369b0-e95c-4c08-81ae-df1e1ba0bbb0","progress_status":"completed","dependent_files":"src/components/Tracker.jsx,src/lib/followups.js,src/lib/stats.js,src/lib/nextaction.js","gmt_create":"2026-07-23T01:21:42.267991+08:00","gmt_modified":"2026-07-23T01:49:12.0715356+08:00","raw_data":"WikiEncrypted:kNxyuEv6QFzNyCfYOgB4ajSfpo9ual/0oKHDHhmndCBqQfYoK0cSoGJBKtC1QvGNBdzTmuSu2Es/JYlui/MgsRkenMcg9xOZZA+eIi7Z22a25GtwaQ0BwhOLGxWylm4PbohQSevZcuoQQY2w91O3IHpPRjhOdqKbLstSkih/KdjMlopF6RGxn/N5f/Pin9HocHIEunglbFQJtgFF7DOBsJXGCtXrJboGUHYb7RNJvNTtocEl7RZR9EFhFD4adI8N7+BUsvyCYbHNy0+E7XQ2deoakMxRlt+Pr6jQ0JZ/O8MhE3E3cKRxFn5QTJ2FWCipiw7A1o9WTIkL3l3H5Wkzgl4x0GYVLBpjynoTAXGCy2ps5UE98q9Ag5btmijtbXhjOodGndAeSQ9NNziGgGIkY1aWCbv9EBq62hMpApHK8hHPLGArCe0uZit/Uu9n7cUtnbism+4e+JfiWy/WEX1rP36bmCk5/dj0df6tnYrCa6NX97nWZjfiQdVM7aa1VVmyg17x12MBth/rgEvQ/ZRdpUXQqwpA9owst7sGbOp7dbj87D2tdIL6AuYAjfZfKom+U35yPySymH3LWPQnHLQU4cE2Hg/coY/bzoJjAHVNl7/KK0rHBWJ9DpFJyoJ5cJgV7CL4+XEJSRiLhICyYplrWu9SYjtN4aRNCxeS3W9W2Q3sEigdTkS11k2VoJohk7g4SsxIrU6uA2d8fjbgs1sSmefvsy8uciAcBtTvY99m8vMCXmsNiy3+afQ+sVukC7bRtaBS8raqe7HtzbuCpyLdel0PyCvE+/TnJPBY++m05rf4Nlmzc795HJFHzmOaZXfPtPYQ8nyXUfBlXAzVmNjvhuYZw+H9YVj0nLubDi3Kv6oFxOxn0yUyLirvKKyYjAo7rCRxGumY6fOyf4s1fI8qMAYtPQO6Rx9ziaiM9adrqoGsqt4qbKkvLTJiVTG5FGmRAioom+PoJ0yablg46pXDqtRxPAL3ht9/3ZMhTDNsrLpvCDmTceXOhXBCFEpmO93SUyJWWsHPAeauZCIcIffXR0CnSTADADQxmZ7RLFViiFz9w4t15otOzDdnRiuVuUiTFpcb2jloYFQbnrsVtOZrhrbua32uy33PGdDUa9pl7+l55bRCNEScRivmZoZr7GQ/kI3vKA4TpUZf+3KLkvQKc2PYD6VeMF8uuoCazqc1bBRumtRUgoULox03VKFTGmrdpU3fFOwgGZD6bQy7SyC0SG2Sp3/1mATqqAzUlqRcL+bGuwvU6Qw5C8yrtbUcrdf6q9CayQGDwMoxkvT1PoDZVALcHkPaOoUATP/93fAOAmlWcjMsbaTkvK8SehzXciHSkkEA6Hd04l6KZ4pE0TbFSn1KpzlwvrquNAm1R/T7S6pKy4W5VYnF/jbDPxWdokfBZYSm63b53v7iCDob7GPiDf450sqllFeVgCVZKdVc2o8=","layer_level":1},{"id":"4e6884c3-ec96-4738-b40c-ddece5a2a3a8","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Component System","description":"component-system","prompt":"Create comprehensive documentation for the React component system in ApplyGuard PH. Document the component hierarchy, naming conventions, and architectural patterns used throughout the application. Explain the base Layout component and its role as a wrapper for all pages. Detail form components like ScanForm with validation patterns and state management. Document display components like ResultView and feedback components like Toast. Include component composition patterns, prop interfaces, event handling, and reusability strategies. Provide examples of how components interact with business logic modules and handle user interactions.","parent_id":"531def32-f496-4527-aa66-895ddc7ac7bc","progress_status":"completed","dependent_files":"src/components/Layout.jsx,src/components/ScanForm.jsx,src/components/ResultView.jsx,src/components/Toast.jsx,src/components/Settings.jsx","gmt_create":"2026-07-23T01:21:46.287861+08:00","gmt_modified":"2026-07-23T01:49:37.790785+08:00","raw_data":"WikiEncrypted:4Zqjl5aZEo1Vv5NKBpebTqt3sxXxOtzcMOpXIMlVq/QUqZDQSUf/+ygZOoXWrSyqZNBedKPHqb22YMOY3BuOc88kS8JQKhI7oLYnP+zUQNj8T3sZwvJ+IPNIENG9q/6EN6AYDg9hY62R02IzeVQQWhekdrtt9Bdh9geokW/EhlkZQwusqQfATru0wE7sgoZmU/v5eL3ukYXqCVijKwaBmpwaI0Cv9xo6j+h3cM/eAowJ74GQJWYGkVWk8jNYHWC+dw2IaIzYB/bQbbhx+R7vE6sGy8OvQex2lBwXTcd4ILhLTo35BBN+nj3YA5Q0M6MmGQkxWzGaoh6rKvojbSoEHdH8KsOYeOTD7Xpk2gbvcU30IPd54ybgHsQZrijzeyUidf8irT11Uj1NzxlrXXvOU37ViKUX9iVUM2AluU3HQhc73dkxOaK6HVwQ7ESpamZcESqW94ZFkF0MFI81J+nClJq1nvb8/h8EolXrOa2JtzpnPsf1Kk3GRJOUL1XHZcJ0Oyfv924YPdhrywHFToxGPXXTOHA2eFglJyY2gEB4e45L16EhizgdcVQrqH04WzTdZTYxG+NcfZe44s0yUk1wba5nVa86iOE15TE+V2UTjYuDLW8MBvAAWqgFRbP3aOcjmb/tz/Bsm9hu702v6jwKG8Q76y24AtPcAM429x0+ZhnmCjkVaUix8FW5dpxmlW6ZBwWBtZXm1cHQDDUi1LCtIX1AMYIWubh6u5WJezKPIExknkBEoWCY36SoaNvZBAdipazu7cMmd9/DioBSuiC8OVvAbdehqrymETFt97WHQ2UlDLovBww2g20Ysv1ikyxu/zvIsqpS77MdbLvw7Ndj9/dZcYKmn81iJgtCuzF4sgfcE1Dzm+bUJDiDJp3s1tvVuZOpTdfIZONXlNJNxM6S1M83vcPB4rnVvrOAN2c9eeX0HUexVP/d/2W6qZJ9CEg7j3N8qezkXQDf/iWe/FR2dtGN4aCcBNOMEcVvUM0mK13dgjv0FzK2OyXCCI++UFhRDEcRq0RDGLAL8mAfytkqOARUX7OBxL5v2YKzcMThKzc/L7yLkJ3JzklJV03dXSZEMnSYAqoI9528rtiFwI5gr3jt3FYFbDRsqm+Ul45qFbJgRvPUuYbQ+VitcU/nnO6l+uPJoeFgHIcW+GWWWRyPRYdm6zXPLqoDWp8oLcRktpF+k/BA+Rn7wU37J0d7iE3T0vB/nVW7hlzo3Pbmzh/fzPlJgyrWkJa1qcU9QCevsZr5cRT9SKcu0y5g4kQE6zx+Krj4ETlZ3SpyYz9JZjVZuNuN1EUyoD5TDtTyjXKzOXR4/HDok/q96TqmCOOBV1ttDsdqOmFAemjCJ2EhLEGGvImea7DzDo/XXn7YglohEF2fmsL9OGn8DjlKoSoe86jGWF4R2F4afQNO9JO5gsFjuSu0acwYGUGFoZM9FHePijFXUDsB2U9JzFMhnC6dMPuu8Ip8kftf+VX1iVFV+8tCuPxQUBmNDpXf5cj0x1T0OGI=","layer_level":1},{"id":"6dcdd10b-114c-4283-8965-a6e63c1641fe","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"System Architecture","description":"system-architecture","prompt":"Create architectural documentation for the ApplyGuard PH system architecture. Describe the high-level design patterns including component-based architecture, service layer separation, and state management strategy. Document the technology stack decisions, system boundaries between frontend, backend services, and external integrations. Explain the data flow architecture from user interactions through local storage to cloud synchronization. Include infrastructure diagrams showing component relationships, API call patterns, and real-time sync mechanisms. Address scalability considerations, security architecture, and deployment topology across web and mobile platforms.","parent_id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","progress_status":"completed","dependent_files":"src/App.jsx,src/main.jsx,src/store.jsx,supabase/config.toml","gmt_create":"2026-07-23T01:21:46.7715639+08:00","gmt_modified":"2026-07-23T01:50:12.3155071+08:00","raw_data":"WikiEncrypted:gWB8HBj+8+/15rQhXgtMjCy7qJxJBEw3w9EAqc5OttcRMGBWFnzhKS/AF4DaQ4a+7Cm8kkdqFImh5EFH6PQtr3JYvgX7p80seftsE2rtgvv3KoapCPWhUVUbaubWa8nuxOwEV01BDUa0pJ0p06VXOmpGds9BfyxZ2UunBPHDnZ9ORfywjtQ8bSYrSftga8o3gdcRwoel3OfIsGoF78bS6lSRkejNQkh+xsdmQ0l5FOYpe03c6hqPfwsJiJrrcXzFnmhPfSW2+5qHA5d37k8m82/Lcnn/IzXWB6iOggerP6fLgIDHhMevuneQaWBlLniTsoDyo8lhrEWJbJMk1w1dXt+S1ULVJ3e9FO6lBkd3Y9Q211b86tJbjiPkRu+x4sUnP2H+ZZH3IWGEANEpwfVvp7JzJJ/CuyEK2QBnvMdZmseH8PBw8j3iOlYnVz5bxL2uVlSCg4wufh9bGobt+yRI3nFxNhR5CvbQ6BKtQu5jfp7ErKmlXL3Nx8ZKXIiFb380tYpJ5690UuupnH1ifKCCNNnIk+FC4c78VPZ/yH3SONFF8knuB+qzI3xpp+aRVGvsUdFp0PAljPhvbaxjEDftos3Z51sl5qcwdqmv4rPG63mzS8xTB38T1U14fTeYD3Hoef+BoAgnL/yW+lCWWt02WLHKzRwBYwRHj+/NtZViUkgZqz+Z4foP4peX5zHK5duxPk2/y+g1XEgGxqYxRCkHeMRV+UtsQD0uSkOE9fK0ytynmRzNDRp33xHkKtzjxC510d4flH3DIgC39VysByVSO/T7shLfNAPd+Jb9RAAApPoShjftrGbDRDNg9LPEWYRyZ7ViwjtEWXHAG93YbCq0Xcj1oOzuyatoQ7SLbZ3ItGcsgYPb0/3W/K0/HWYWE1indfql7b3dmh63XcJ/cH5gsoKAxtN0vuAPN6uCk677aPPpSZ6DwH/xIfCHJV57JRXsL69CT+EdrLCVt+2TnglWqQXrdYwMSr6QnF2L+e5ouZg6uuKulJN+nhjJ/jV/8TwR7k3BLusglIrCfRIWZL8lGk7ncr2vhgRwLxw/Ly7hdMIlXF+8NNFLHGyIzRl4/Nrl91YG5sDz/VU59iATC/5uOsnewkoLhICZt125IDVnn4iBnnxwsNgJt+F0CTOZKm6IVpD2M5qfH9142z230CqlC6y5XeCNUxL/c7DFSa4D4p42tSt4UyhXy4dQZp6tWuVg2ZVXjl21+FcN7H0tzScqz5xvMque2KWzf3AZ9C5rm+Jp/yCj+tG9MgpKIOA5kOuE4HP0ENIG1X3wH4WTA2urYWaCLj1jTNxIb6rFbtj1vYS5nZDSvqjmfT8N7Lir4yR9FR7cGiKoHiASm6ut+vyYddXpTieSveeM+SP7kfUGd9hzagaQRQ93NmgVAVuJkKsJHIVNPCafexitbTrdd2ybx0B5iMFxxmyzvrosyQ/fcJhuJVtSPwJ6Itxr/VKqzbsXu1NB/+qBn+VqCOrZkBiO7CB0OepCya/pu/3XX8FWhBOclFVClPwSgUQuMkk0CwSMy6xrKdIrrBjAel4tr2vf5A==","layer_level":1},{"id":"6dc96b36-07c7-4466-bd10-1f0ab817577a","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Resume Analysis Engine","description":"resume-analysis-engine","prompt":"Create comprehensive documentation for the resume analysis engine in ApplyGuard PH. Document the AI-powered resume scanning algorithms, tone analysis system, and content evaluation methods. Explain how the system parses resumes, extracts key information, and generates insights. Include details about the AI integration patterns, prompt engineering approaches, and response processing. Document the tone analysis algorithms that detect communication style, confidence levels, and professional language patterns. Provide examples of analysis results, configuration options for different industries or job types, and customization points for specific analysis criteria.","parent_id":"1968d404-384a-4a0b-82f7-a66bf82b925d","progress_status":"completed","dependent_files":"src/lib/analyze.js,src/lib/tone.js,src/components/AiAssistant.jsx","gmt_create":"2026-07-23T01:21:47.8590099+08:00","gmt_modified":"2026-07-23T01:49:59.0960746+08:00","raw_data":"WikiEncrypted:j8yw4eIMpvYmsVxTwcxtHUAOloyTzlaFDPaTeGoGtCyMbeu7S7P0c+Esxx1KB40qrF94zP8nQeZQsV1GC8MnkQWnAvKD4Sc7ITBkZbt7BNXx1JaqwLhpSZE3pXZx029KH6yF8Tg8TmAzDxih7gF7w6aIAdW9QRmkLsQ39fHKU4XZKqQ0nh1p8FCZrBGGitMV9yUSwiWQo/4fvQ4R/0IufHLqp+3Nqu5ozFir0uxlckzX58yN7PoRflJ4xRqPg10Z5qJicBreUiiMsZ7gPbpvwno0YF0/qFmTToZUEMnCOndsi/rJlpWD5yHPLeoYTAUN4xDtAzF/LhdaayK6P2VdBXgT6uFibT+Rj2R1fosOY0SeqEEJ7UxfVu6LduBfjlQOVZdcJSbv+KG6Nqrk0bAo/tAh7YByOoA7D3zZvyO/HnLc3yLVR3ATgEVkK2FrFSW+xQXK6NXp4JTY6+TUPrHEM/80gUn0JJpmht1Wv74Zth9pdw9zXC+Kt8J9/bJmAAZsr8Xt9pMREVcRx07p865p/ApCwa+mAWwwYXH3tMRR8EKf04csoaDnlecbAksWMJW12v0hmmhD4Tc1s/Jgjf5/oWAOC/UleGDgEy+yEOq71e/aJrYsPDaYlYSd8fUuXYEChXgSAar/9FcaQKacfL8xw+ydXDOXOGM8cNpUmySfHXKYgT+gu68S4ORiPSD1wvJrwaGecmQK6B9w3LhKxqepvETfTCiJQ4M+hcb+dbPCvyd56m9WmrN8yeoPLyUyuK7hGlMCv9E/Z9CIhkGcg2SMdDBL0VkZ8Ef5umzaD/I29riy1kWiZQ1N979vAQ33W3hKrMiKMrOwxYXhfM3AQOM/Xj3+FK910pwO+a1UpK+Hbz2DH0RymDLavYK4T7Rxv2ggE8R8G1fri71vkBeNbZk67SU7+LPtHmE5nZR097a5NATnGlp+S/bEydcPROQmbqe/aTrULaZwkg8URoJDO3DHyWZwxxb46mriWI+wrWUw3PcAhd3VCl92v34NUf8C7SeYyQIeUL++nKVBt0/lskqev6fA5bHHEayUVcyoj7OVidhISkilM5rhvIz1ioi/ue+B6A2deK3AGfUAKgLdAAkzZwcvZsV1xslRLO2ZYDGZqiOylTV8ohlVjYjrY1lJD2g4zhdPkVGCOFMIvIVP48R5VBXNfroMgQbGr2zawn7DEq7FAUPjijlWQjSx715KrgUFaC/VA98bni0bIF9wOKB1BsDRM0QoU9vyAnAyb8S9GA0ebtxGalqcIuuUAtBCyNhATUYf50QJbGFYtHsblzWA0wswYW6HdTDwiyo6zI5/9Ror/QdLRii1g1Fl+DqUblvm7RWX4sd+ugf/4VWzYVCyJE30zwddrNYuxC+oNTotycOFLqv0JB1L1Fxw/0alCR/EIcoHuK3SzURpYciJIuyNCzPVNXWLrqqeQvfLTq83YXLKpoibWxH2YljsSgMrGBqS1fIEbI5Wtm7ghKEepGR7yg==","layer_level":1},{"id":"b55383ee-0af7-4328-bbde-b36f5eb8efdf","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Local Storage \u0026 Persistence","description":"local-storage","prompt":"Create detailed documentation for the local storage implementation in ApplyGuard PH. Document the data persistence strategies, storage architecture, and offline support mechanisms. Explain how application state is serialized, stored, and retrieved from localStorage. Detail the data models used for persistence, including job applications, offers, and user preferences. Document storage limits handling, data migration between versions, and backup/restore functionality. Include performance considerations for large datasets and optimization techniques. Provide examples of common storage operations and error handling patterns.","parent_id":"4c08a624-9311-45cb-a77c-0010b16eb5df","progress_status":"completed","dependent_files":"src/lib/storage.js","gmt_create":"2026-07-23T01:21:51.772281+08:00","gmt_modified":"2026-07-23T01:50:22.584061+08:00","raw_data":"WikiEncrypted:XMvsRjFEcSrjMOAT9RAdm9O4LIaLRHUOAniVL3dWNBSJQxQj4YXH0UU/TXCEvEc2is24uTAghqduv12XZnT3w2IihMS5TLONyubLO2XL+NM1eHSayK1LywMM8Xr5TxbHoVFDpod9ccm7pW6dn2c/TviJFkYcIwdnrFmBwszk75ubjYC5ONqM1LzW+lsUF7331+3EBv7eyYHd+EZqcV9JW7jdnKFA0nXSG1lDWiNDyHJ1j8pgnWaSLGdJ6xS8Acqk9HCnwYt4x6hIlmTcBkYFVaIEtqWgPnch+2hrxONwUJrOxd9osNVCCCW0ZZmto3maclJCw7MZLQP2TeOqlO04jhg1k+5r6JEdMqI3A5ZqarviKOzF79HpQv6GWNNHrp3ejHAHF7mNnm4h2j0THlV7X6Tze9AQp1s0hD8QE+33ZBJiCusQA3ljQkuKzb5tA7yidsKOayuZllmafqsks+Iuekmyf/gCyw4Cr70Ln3+bC76UzKnxCtPjeA3z4XHQVSrbPi0VjQJ4XGVmlaWEZR70KR8LA3lqsS4MvVhQyTumpOuVT4DBfpnow6E922vDjNYU2WqL1SvAa+LH7i9xW9kD3jlGbg/QjIOTT2PYD7sByJifvRawS8WubSGkIBthDJtg8Ot6QyVUrZsqbSD8HrFZAMQUWl9uYNC2+I61+uNGUqqaWjrMEH5ZS9Q2l59QOoHvFi4bH2Xq1RgW/xxyrFSwy/q9oA3okKWcvv8wKPnzSZ5y3hFNNjYCIuPWt0eo1IjJSM9ECTNZI6GKmrnFIBe+JIbmNyjY2oiDmi9C8+GrZ/7kdMuUizgrN8lEOscNTcWoofO1G63EsY4PiwdhNf+7/4QcDk7BEwIMMvrVYEgxWrfNoEfsISDDMrh1pv4+rMIv8ag7O7EW9XhtZppDcS5aD234Z0SKzLGQ3fjDNes/fBo5O2VmpFP62f44Onf5t8JPyTEe0akdGauq+Qt0tBMRr4vUPkWRxzjL3FCmtRagnQfpZ9IKr16SExcqydxUlr2J7IifgK/QSONQgVnd+4BKEel41T4L4Sas2lwuBvKulOSV7HHe53xojTGT/nN8O9n4XglpG6W10TfjJn2BFhAM+PS2yADmgHI0y/Mn1AI7qj4ENy6WK3danaeYYUIwZbg9iqEUiU1CAlWh8p/Pmaj9LP/gxzJxz28bMmGlxPMasg3wd/GePllgjOizxNk8uQQ+JctIqr76rJ/DKNAa1KaR1S44127Fzr06DfEkp4MeAE05o8UdVtXxHLSZh+7NuLeo","layer_level":1},{"id":"66e799e0-8dd6-4668-ac43-a4bd7c42a5eb","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Payment Processors","description":"payment-processors","prompt":"Create detailed documentation for payment processor integrations in ApplyGuard PH. Document the dual payment system architecture supporting both PayMongo and PayPal providers. Explain checkout flow implementation, payment method selection, and transaction processing. Detail webhook handling for payment events, order capture mechanisms, and error recovery strategies. Include provider-specific configuration, API integration patterns, and security considerations for payment data handling.","parent_id":"0ed40228-e6f9-4241-94eb-1ab69560f488","progress_status":"completed","dependent_files":"supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts,supabase/functions/_shared/paypal.ts","gmt_create":"2026-07-23T01:21:52.5978793+08:00","gmt_modified":"2026-07-23T01:23:39.7502584+08:00","raw_data":"WikiEncrypted:lcOTJMVsDrhWtJI8Bt/2JhlkPSVt/rVD39t515xLFL+Vt/d26dt1sKuhu2xRz28J3M4oGa+12eucWGmHYhTe+TvGjJCrYkEd/tUdXInl2Zp+lBmuY2SMMApheemqxdH20+Z+0n1lfL1WQYPNq/jLwX+jYimgCXhxRP+Q+6dQpoDHRcFr7EqcsOLcB7+w2ejlsNV0Yhz+GgVn/01fvnF/JLSo16gQp9iENQn9I+kiFuMywMJu1gTqZ93PoOqcwGw9LHgQEra9kXtgO/GSJspufVEUi4YmJWuZIDs8sq3ehMqSZPbczMdaFV1zvVlsRYWkd/z66avsXHsf9IKlEZmHSpSI13ht8k90TVJIbhsEB7uULBWMwKNeyJmcdcl/j1DX2V+kfTOz3cfQXTNCD+EH9S8KDVRfDjjrPyxBNC5vRZlmeW9U5TYJZXcbHcsxwj5yEw+M+qK0hDTsgLlIPKoqfPbideaSAq5iY4nL/EaKHFbAdRXySz6QkblVVY91wUVOXtuBKwOVlp3gyO1lx04WH5W83FrT/RsI6eo783pNJCatoQ7+7NyhnqEFC55JIMydj6KCbRFSLnRVHXe91nWkB6nVBitRMdQT6l6sVDlPQl78TWF+aNiHkJmYwcWKPF2vP2xDRvNHyfo129ImnQHTraRofBIUoE2Qac9Z7aRFSP0HyKeI551xW5TnGDiKaXVzfLgEp8tryc5RCDiBJ7/kyV1s9+AvA74CUHuS70wnc246y1ZA5Pc7ver7EgREuWbI28rGtXqBQ858LbwEJEt2sj8LY4WE6MsoyS8Z0YggEqDr502h2MPLVFzkubY0cZVjOvDf43C1eebw/uiPB37WbuAIMFxr3C72H2pQj9lcr428v20MD0Ij5tPFch0CvE0ETqAA5bHN7mMExS93bT1WNQrLIM0Ngc+yRXz9p5jOs0cZXNtlQpnqwscRjjFf7EOMGJm5IxFUmE31DYM/e2DLMBtZ/q5+J2yHkDuAthg1e76lGJudscop23/UL58nBI/WXDCxnCJvZBXmbWwZWEo+q37Et16g7L3sJCx6v9+PvbCUtt1qdFWGsTZh7Fr6wFcRC9goY1mCBJePibuvtARcVjy6++pyEfs/RXfgT5qqHCxLUSLkEjlrTqDOBo8EyJaDKEiz5yeP3lB5Ulj/fRgKdJKb7HPE5IwMYugLtCoM6SRrSMlcp0DSPitRQrV63wAM2ClpKEdYTpi0nqcC1EvlAxnMylR6qywQDXU7ylW4sSW6Ubaon3b/2Wke/Q6pesHt2Jddt2Zh8IfPI8ThiOHC+w==","layer_level":1},{"id":"45127b67-19f5-42b0-b44e-63fd3d377aae","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Edge Functions","description":"edge-functions","prompt":"Create comprehensive documentation for ApplyGuard PH's Supabase Edge Functions. Document each function's purpose, API endpoints, request/response formats, and authentication requirements. Detail the AI proxy function for resume analysis and interview coaching, billing functions for PayMongo and PayPal integration, webhook handlers for payment processing, and utility functions for data export. Include error handling patterns, security considerations, rate limiting, and performance optimization strategies. Provide code examples showing how to call these functions from the frontend and handle responses.","parent_id":"915d9267-a5a3-4ccf-9891-2071a4e7b621","progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts,supabase/functions/paypal-webhook/index.ts,supabase/functions/download-message-pack/index.ts,supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:21:56.5069127+08:00","gmt_modified":"2026-07-23T01:24:05.7482886+08:00","raw_data":"WikiEncrypted:UKlunF/mHL6mryERVz9Q8ESmyAi2jlsEFmS8Q0cw1ujz3owxiAZNu0hCdL8euKQL5U0Trc61uWBjrpE3SlIaoDMd8locfo4yT8J9HoVjuWiKUQjQ35rXqeln6lD2gPXac2Z0mE2C8B9TwlKi2H9v2G/hYcQuIlT5DbUgCL8iLnbh0kAAZfywQmuZ/26Jrqdiz7PTc6E/jv6WqIikJ5mHHR/KC1wV23GyhUI2Ln4VzGXQmCIQZss419Ge4NrDq70WqTVSVsRmU/qp//+7hShAovVhFsVBtQRaKhXtctPOA/AI9BDdNUt+sLdEpBUnKbEqy2K4apJhwqfVpTCyov/aR7OuqEeMNkGRNt9Af3Y4Aq108r4b30hJ/9VQsCBcO3h2pKOI3+O6OViUQGCqXRktBL94IFaXVTxaU5kolKDHjo3EOLOnmOyqsLNGblvB/c3vrHCdsAXg2vknaTX5o+nbbY43D5bUEZsHhF6NssJvwHfMFw7FrJf4DNVkZ9yR+cveVsfJr1oDPFhsXdrIA2ZocdXk4U0BX1npsVljelNWU2C4/EcXCAyjOiEhcezdudgz/3ZomreuoPxuU7ShoUlQ+DT2+CITpn9T4aFuvPPEJh+7FlfKAU6S7eRDl2dMZpn/ZQ45amm0oNdQd5FDL5cVA8w6JkIhS16z3Hu0AZUoH5yXKYnIluyC5mcjixrreGktbUtVv2SzrS8pOCHAgTT3kLWKK9r+Ks/xLpwxGMJvTqF0CaUT6VZpkU/rzcVK3UsALBo+eU18oTxCXwIZ0k2Ez9r+QLF0d5OpTlG6O3IY2iXg6lMCGIQSbzwojFGTrNZgfrbC6SPcnqaH1/uVzfs5KKqXDaS8xS7hAhPJZhzOWBPRt1QmvVhS2DCqdxBPrkCePH711iRDPoPYbLSEXj/NOJMQ38p2LJz0N7vruyEslut+3o6QGKqX9VyfhRXW6xNdJFdc2C+K9H6+B4anXEWZzS1qzZK24cJqUMTnInyTaZWsKRoVbGebj62Zvi5HCPys/taazaTw340gD6DSRIaQhjLQSkBIjizLvyn4xhNFpftNA0j1w0Q+0a+PuLbLTkn4QHATulccOTWR9w+04m/EC+QO0LXHBd/rIuHtgv8SRklQtLOCcjBXzBcKieK7UNaRDKIsUuru1RUWfW+6eDlMme9UoCT1Ll9frcrBI8J6NajiTFNWgAKUfhsGahLlGoxLtSEyfO8L2vPf1nGNWz8UVT42MhOyudfc265K8bXsRwHPNIAErdI/sg7WkW3qMyHGFlc/DgNsSi34ZsV8AAXaSk84qdBKCUOm2fL/pqvkIitt57O0Q/1WQqjYThxw8geKCR9NfORd/jjCRlprmPdDDPbdXDi+C16o93XYjA47x19/mh1B7SHAC+1brmidrVqS3kOdlPG3ULI8/z/OeRk/4vTitfvkmvYXQIUWJ040YFHEP3H8wnSXG7zCOjPdFfyZdKKZcS8N1K3G9Ln7RNP/HgTNNqQ2OruyYXUr8XIAZc5LFxxEqXiAMVY7V/lS/fCo4HnPQk9mfUlUQn9XpgN18jXz7nIe/3PDwKDbbnmKlvPdqXjwIEThQ00OLmUXYnqqrUVtSxAcqRMilgibA+DBvAVE9RpdTpDq+ol10m+uYwwCDII5Qk81RlveTMxdwUw07O5Phr6nP0LU8N3Fw5y9m46ufgGzl1g0eSeVPkqe/V2D/ebTJLVBUhGiu5usrCK2","layer_level":1},{"id":"396a3cd4-40ed-493e-a4e0-cb04956136cf","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Authentication System","description":"authentication-system","prompt":"Create comprehensive authentication system documentation for ApplyGuard PH. Document the Supabase authentication integration including user registration, login/logout flows, and session management. Explain the authentication context implementation, state persistence, and error handling. Detail security measures including token management, session expiration, and secure storage practices. Include examples of protected routes, authentication guards, and user state access patterns. Address common authentication issues, debugging techniques, and best practices for maintaining secure user sessions.","parent_id":"6545bd99-a4a2-45bf-acee-bdb022c420ed","progress_status":"completed","dependent_files":"src/auth.jsx,src/lib/cloud.js","gmt_create":"2026-07-23T01:21:56.6514408+08:00","gmt_modified":"2026-07-23T01:23:58.3747194+08:00","raw_data":"WikiEncrypted:uxAckj1IXK2TQH//kEdeBLXlO/kfAAqZjShpoDF/Lwy2VscQdYqR6q88sG6OmGkHJT0JBWifMfILW0uPvzceLhXC2aXGWGYRlT1LGa3Ofj4+/g155q0jm60o2/2ZVKeu1H8reHBD0kOK0Gxk0yW+mOLx3SN3QWjAKPMnhLXKdCMAkITXy6GZX2+c84Ctb+XcK0HvzAdP79wsJyIsSGoIIYZ8rGD4Tn7A2ug5tIrDRwssW27i45EUFIvr07UgTb5taW8mNwPVvPEbk0KBONd9IkraLJFHu4zZS1qBwgt94ular/DvxqA/ol4L5LI6DB/OMFZG0xrMWuYZk8MW0NmAU/50vPrT7m97YnTqEQMEsmWoYjhui4yQVjko57tV2Rr3RLRPqiX+P8uKa/uipgCdafHGRGbjf4Ompvghfk7vd3FPRnOCP7o9pyPi9gotOdFLUIz3bwuQnib5+wmWwbSzaYSJuyJhb4X0XqeYPGxzQZDy3Zn+942pvE9C/OdbHE2TWz0n1awVrEifz9W8coE6bf4nu7CrnMBFgRZzc8oQL000CH8xLJteCc7IMbT+8NhQpq0y4CuIHR/55Tt2HMDt8fIJlHMO2ExRBwK+B5KnK7Z5dMonBby8fMi4ZwmhcX+jdO+ZJOXGoKgNAc4gB23SUvcfa5mM2uKP6TD3I5RfO41loKtgjv3YsCFOdBGmdzcYKNqMsfdnrZq4TWj84pWivSxUH30XpEbRE4++e8Rw96GCJWiQiYWEJgimWkudOzDIhm83tqDMKBu8EIVDmMW9w/PldHZPuOp1MWtIGct1YymNBoQBrcAAhoaR0d0n3HzzfmEcCaNEnfh7CN8YRz4kfcMMx6B8sogf/iAeNoYBKI+PLYiIm1Z9j9ChnLR6j1R43LWGdFUC1ov/LUtu4b1OMsnaSJgeCW3+8NoOfvXrJHeKgVHyw6UBxNt2VRCzwyyRNXozVNGMttLl9WMNYN/jORe2Bi+0QWNefmFQdkrlK1RvpuAW8JAB5Tx5p2X2Yh7ClkjzM6Tk7+XjQJPppZ5mkYpGC3RGa20G6C7ZQVmnE6P17oL9T13ZDOh+GfkbUz6Z+tkPm3PYvgXKLCa8gVkizV9XmKoxdpdgeqR2x8hlHN7IfDvitk5IDBIA2Dxp76ysZjioHiAxZ9jfvZByQuDb2r+UZ9WK5V4YAUakTzHnZEBHu+pFikWmgSR48wmBrCi5U1lJCcbcSOT1lqVLDeJsIFmvcTuydiKfss87JBFljFWMDFFp5zrS7BClNNQA2aTQRDEt7ij1BrsQgAlzFH3o2+JQnrCbz3cYMWgvIm0g/1RAI1G6XYr98ruNgwliUIgUhPMKxN90fHQCkX4CzFQVppldF7syUulW/3ZjvvTriATtVQD/l/KEbVyyuy/OnGl4","layer_level":1},{"id":"9ebcd167-847f-41f2-972e-edf32fcd8d66","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Capacitor Setup \u0026 Configuration","description":"capacitor-setup","prompt":"Create detailed documentation for Capacitor setup and configuration in ApplyGuard PH. Document the capacitor.config.ts file structure, platform-specific configurations, and build settings. Explain iOS and Android project initialization, plugin management, and native capabilities configuration. Include step-by-step setup instructions for development environments, dependency installation, and initial project scaffolding. Address common configuration issues, environment variables, and debugging setup for both platforms.","parent_id":"7ed0042c-9ec0-43b4-a5fd-2e4537db9eb9","progress_status":"completed","dependent_files":"capacitor.config.ts,package.json","gmt_create":"2026-07-23T01:22:01.1318659+08:00","gmt_modified":"2026-07-23T01:24:28.198237+08:00","raw_data":"WikiEncrypted:gKP9HYHAokeBckJVfvEiH2u68TK1s58C/JYvbUtiZT23BF3Sj/PBeZcJfw76ecXAhtOkvULUBfNQ8j+B2aKnIUirrm9jD/e7+UIrYnjbYPMED+Fs584PK6TkgthV4f3PqW4z+Ad/mTT7sWN2etcdFqISin658VfLwCYbyM7FVimtkH23wRsg5PsnJiJlJcXpiLmZwzmHu/eLZhX8XzJzTeCSuZm1WW+OgU/qIoFZTaLbXW2QgrUHIw7w9Ck9xDE9G9XrJ9cciiHBuisO47vrhWkRnDS3vKIMH5JcPfxiWdEpYR96GQh7qT2RmG4vZQIt6Ki378pvHqBmo+mQ54iE+Umn8/GLHj9uiAp0J/WjLCQ+SgKzrNp6qYsD5QJtlG8uLW1v/Pyi2bPWugOI/q7E+xtjeiz7J0gQ8/Qlto2lnrT8ZH1j3MSVMP4AISu1S2HBoPBQEBH+bivrijfQ/hF+rjwbe3I+0Hg3nifZjxDPVnukh0VI+5yK0l6iLrVwCmIRWRQ4IbGZ+MLSoJB/O8jCDYVYbOOSu6EbiYEEMmltnQ2a+dsud59HPv2jUgxBhRWTpA1YAPa+05NGjNhyT03AOFN+xbepT9b78F2jPZcjaS4OkspiXLOHHPZJclDeTEH5cRmo5IQ95JbzMhjrw2yjtMN2L5dq8vrOxto2AmAtPHeum9STKi3TwnKz2LVwcvXrbbpNM8587xUUaQpIVkA/nVR+dJN3FuVMn66K6yJEoH2PPQ8LA/x9p8BTr7gZ4ENuLyr/GETYDQAlkXjSzGJhResW4xFlZb3bvzfrc2EoR1RBtEyTAnd5QExUy4VvOVXmJsOQWuS9yZh6HrTPfeQ3h8rSiBxDgU4Nt7LkdjeH0tbjXScmv1w5CZijIMuc/KUXF4aVgNwtN1Ov/2dl5BHP78t6L2zVr5ad05VyUfgeQOatpa+exzE3v1fHy+DBgiTk/X+2l2zvApocxeb9NnC5I66sogXIV9TtOMu7QIgDdJNCeOrG+4g+MMLgJokBUD/WYd4xmefwzg38+unqgUVZMCTi5sCaF3qDgAQvCt48+iCfKVrYoqdyIUtjwjxyNDXac2gJ6DkDyvndcty+0PjmpxbFj3YNk8uOIeS8DYMfyl3CDu4vCjOJgo2/i5fjlNKHXehtnAl0AyUs6zCntw2TkN3sKa3skzT0VIgbR04utMy9gcdVodXF+1dq6/pnTCzup8nql2d4HDaiYZ3zYcCmYQ==","layer_level":1},{"id":"aad58f1e-81da-47d2-9000-d1e4cd8b660e","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Supabase Edge Functions","description":"edge-functions","prompt":"Create comprehensive API documentation for ApplyGuard PH's Supabase Edge Functions. Document all serverless function endpoints including AI proxy service, checkout creation, subscription management, and data export utilities. For each endpoint, specify HTTP methods, URL patterns, request/response schemas, authentication requirements using JWT tokens, and error handling patterns. Include detailed parameter validation, rate limiting considerations, and security headers. Provide client implementation examples showing how to call these functions from the frontend, handle responses, and manage errors. Document function deployment configuration, environment variables, and performance optimization tips.","parent_id":"c870be03-f946-4159-9251-65e9a33f166c","progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/create-checkout/index.ts,supabase/functions/cancel-subscription/index.ts,supabase/functions/download-message-pack/index.ts","gmt_create":"2026-07-23T01:22:06.4255134+08:00","gmt_modified":"2026-07-23T01:24:43.4370839+08:00","raw_data":"WikiEncrypted:UKlunF/mHL6mryERVz9Q8ESmyAi2jlsEFmS8Q0cw1ujDqNneILHPeDEQVKjF1JevKQ/v9VqaAMixRzzo7tC3hvgMZ70UiAYVY9FYMbB4WnxzbiyXp1TLKxS4tPrcUn9uzDieATYqBTX4MxoB+R8nB+4jr+ZdzfroUTjZl3LhoA0j/+6f4q5kZGwgXcH2jMmUYmnHiRlgmVUl0+YTmydHCtfmqXx9hY/4tvWTuQJyo/PHV8DB+rExVxuO9ZL1o1xxtdjBX6YVqiDqmMPRtO2YHpDPm9e/OEjuSOPlnvstSnjWh95vNGtrbTrDmjtspRHL9uASKDqS/RP93BapYlkY7467Sr41UtdBxopmUlDyXqs+qlSWNesanHlMfe9C4VToZS5he9Bz95CYBN/4wxk0L2oEqekWU6mDs05EwKge7P8omln5AgnOyJmCUxiEm6BS0bKawdYLX6VvCARi5toe7pUGmgxAiK+AoKyUqvqDou/MHn2ML4o4lh1Zehjprmve+OK+h/Ej9VY0My19yIZFAhYt5+ydrcn8VyR9XU0TEahjeGQeTnaUWVUPLG0ruuTz2h1vEVrkNonqHrDLy+sjiswDW0VRfkt0d6YZyGHev6Bpp5jbVvpm7r5mUfBQmZNDO2qW/wG0zp7LD+Ywi0eLyOroinrIK69yd40zi9EIGTmii7Hw2kKGmdVZwtMYVimp2NKrt+UhptBR+gdYRAdCpyL+zeGXfK4uqxi/BZEtJecJGO13d8Ki79FNUs8Q8huQJ8NKv25EnP3WuP9OrbRpTPE0YrKYI15uThPj57mncQsffQKGC2ozRn16lB7vhMxHth7cdqs8KAfxBlxnJfjaKIWLLIAmQtOOe4xqRRNiDmGcgURBCAkufd7WNJQXC0VCQMZVjA9XKZd9+UpUBv5jOyy04BF2/6bxkTsYf5Bp8wLQQkhKfzofxANSWJeiryLcOAsSWNjSPHseI2C0LDh4enqxztdcRjwOxYrfGWHBPcIg6yl3TBA+W86cynkwXJr07uK6nrvk9hSo46ZfmFKz2Vwug6bG/dsV2Byp6nuRaWy2UViVjDKB2Hh5/mhb5m9KrSd9+xmWXxxzdtv1E1XH8kjSOuO0oySnlaz6JUOqMYF+KHBylNBdVm/r++nAVVzt+KQeEhFQcaHYAN2Dy4ZKzFGyf+/qB/oWsidL6TyZkoReVjxdEAGRip+OK0R0Iq1GVRwByp5c5ZtcS9puAsV1pBWgDQeG/1C0z7HDw5UGRkbAATF1kKsSISbuqTgXNj2Dj5jx6lPrTxT2aPupE5cKRMSEeQqTVxv/kImCABL3Phpwp4bKHHhkkyHLgR3nJUex5X+iP5p3LjIMzq7f6R7jGg/qn9F8ZzCrWPaMmryTVmjsWMW+VruC2e/FaNccfnU8O/3G8aWKkYB541jwWsJy4lzan14HqKk0kCfygvvzNPXQDbdi/K2R1cLJnXrp9L6e5h8brCKG14iDOJQX7JXi0nFhtuJ/lgDjTCSrnIMZh2iLmRmTXKE3ATcDB34I0hcsrznkOJaE0u+bbOHGdTA3GPXtoRgGKJopTlI5lQYH3W1eB2LkI9A5PdV8foIYqvDC4xq6wA1sH8L6DvIHvmyNvV5SiyDRh0B/wO5mPrQJy+L0+gFcaVQJWL6daTn6xJT/","layer_level":1},{"id":"0916ae4a-5bb1-4518-8451-99f508885422","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Mock Interview Interface","description":"mock-interview-interface","prompt":"Create comprehensive documentation for the mock interview interface component. Detail the user interaction flow, question display mechanisms, response input handling, and session management. Document how users initiate interview sessions, navigate through questions, provide answers, and review their performance. Include examples of different interview types, customization options for difficulty levels and job categories, and real-time feedback mechanisms. Explain the integration with resume data to generate personalized questions and the scoring system for response evaluation.","parent_id":"531c9699-6862-444f-8f72-71e9b8983826","progress_status":"completed","dependent_files":"src/components/MockInterviewPage.jsx","gmt_create":"2026-07-23T01:22:07.3552974+08:00","gmt_modified":"2026-07-23T01:31:10.4860627+08:00","raw_data":"WikiEncrypted:iJ9cToiAeDSCxmZaktme/WygdITvIqPyGr4CP4W50VJiyDd4St/XImMzXc2UZJeT0YmYJObvRnPeu0qt+tOE4bWmpyHmPeZb/4XOYvlORlvVWjWH9wQbXES3ASLQjtmUDFkdehGfjZjYM/87veHtYrf/jRukCnReSKjmH4NhH01iOarAZA37GyxmPAa8uA/+EgHXp1iIzE8fs2DcN56vuGwGy5UUHlBwqveuEcz8dIX2kmnaGjCZUw9p73Jr1AsOYUCrqszskV8DX5Ce80cka3sEkV8euUCXyHfKA+L8rS3MWqtNaUQ94S724aHN9kSZ3gbbsN2jlsSwGjniBbWdAuVr/pB/jtFTZtdz9f3gETA+F9yJI2yUC5x4I104nRYXPBTweBSY93zrebgdjYXIxFLNlFEIiE9p4K7Vi9H+/OiUx+nnJVFY4RFxcIGp6ApEyPOv8eKRRiOk2RbUn3M+8rsYNBB4BXQLWHEipsSnz8e0oliSm9dqArIX21MhAYo6yc3QRpu6CVt50DYv4MdFsdck9AZbGr7+ukMdRTjhEzwueUZTbSIwEp+VK0+rY9/WroLFRyqXSD2e86aPYjB5MxruaOrcCm4iGmzuTrGD0Nq9lyKIwBVbjcFeWpqmmYK1ydIN+loe1qVVDSkqS3R8pOm+unqDAgRDZHhhO8nEI46/YqjP40RibcU3B9Z/RAvM0GmS7lfADCUzadw/6hzxqLYC8Jq8ZQyXCpljCuwwmN0sxSk5KR++pHBlMlvDMPzb8biTrUcpVF6tPjiTCGnIYx6WkZXNOFOJ4n0a9cO+7DEZfHr6Qm3tnmP+pZiqo6+34OOc9SzOg7NfuO9fXvPEzfGXBZp9YhaVR8OlPew3NrnhxEUdgM2TOwhoaYPcOL47LBUZhCVE0NH3CBpFfWLRm1H7ZuQpjDB7RIg7VZrRew7qnbUJqGXMp9GvGqdDxnB/MvAN0q6d32AOkki8p2syrlEs1Sve+y/uIOMW+mL+J5NqKObr7DjMs8sAwj4tyWUZjVPzqKI5flZ0hqM7NW5FT462nnzpHbpfKNgcD75q3h0wgvabsaQiTB9gGOXerGQZ0pGxF0fmpqHmyGag08ZlTXhBx4tyaAxmL/vzgjT3d7ZvzDRjRqfs6c9UIr/Ze/hFufoidBijbnVVAMJInZbDKULqmBajG2zLkqadIEGX4kphPAyG00z3aWFejY5L3gMMHqGwEHFXTpc6Uj9qAJsgIfD5P8yzqJQeR1eq4b5J3UwIoWHvVt2bVwIRDNQJIPQAV4UD+lczSpBAv19BEMXqCdvE41LUEBhIGzUQPoaNTo+KytYJPgxU2TLuqKCwNTWb","layer_level":2},{"id":"6c29e642-e8d4-451c-b0ff-c6ef0b151c45","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Tracker Dashboard \u0026 Interface","description":"tracker-dashboard","prompt":"Create detailed documentation for the Tracker dashboard component. Document the main interface layout, navigation structure, and user interaction patterns. Explain how users can view their job applications in different views (list, grid), filter and search functionality, sorting options, and responsive design considerations. Include examples of dashboard customization, column configuration, and data display preferences. Address performance optimization for large datasets and mobile responsiveness.","parent_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","progress_status":"completed","dependent_files":"src/components/Tracker.jsx","gmt_create":"2026-07-23T01:22:08.2114608+08:00","gmt_modified":"2026-07-23T01:31:32.4858525+08:00","raw_data":"WikiEncrypted:GL6BfeKX7dOongvgnwY1kPE0gmjVRZ79UmyYdf0KJHzhaY4U1Kok2wcQ28EZEYS9FyLHRzM2jhY/y2bm+IFgYLhsTUW4KqMgXc1LpsZEsi1OFV7DYR2Zw5QIJuVphDlza4pNO7biM9FswnUv9m+ECPiJTltRLVVDzkF3jaLWpxoMY7yoynnGR9cPen2E6VFy+LMAtfTe2idl1qXWXlMIuniY6ZkuJFE4sRhgc6A6KJ4DMCNETP11woGSE3IKWRLfa14TZAhMucInwjjwir/syG+dKctd5R+GcyF0Wh33IYtlOCg4zkYNG/imrTNHsrBBIcUGwzg9m1QCAagj1L/PSWQv0f+WL5TfM+UZU6i7uIgdC8siis9qTy+jExaG/eovt5kBQV+R0AUrtFLjUOAqjZCL5pjI28OrvScylDnoODjP0ITrDkDZUaQSxHTnqu2NCqWjiz5t+mEEHOQ9f7rIe7arsFnV66TT+FSwK60pjhUWO6H3stmz89YNX+THziBuNLnIR+7fBdCBdVLKoQk6B3JJ8t4BMlOYMnf/ylwjhRIp/CgrfC7I1wkMBOKd9DC/RZg6FSDoWH3RxZeRnbMqFYoeUQFDIvNC2duref5lpmOWNEj8GGaZZr9A/gbZ68eQvHNxepuqREPU5Oib081OfuMlduMZIIebNCCefBMfMzJQxWX4U+blclSNa6aUSWyhphA6fRJS366X3mnxWXHnzQMPdTrJiWZFW+GFmYbGJ1fs5bbrU7oWExswXbQaH02Af8kjKJxDBdjB/yZPWlLXo95Ao5HWsUKlP/s+vSYPDP3xFNHDIQ3wM5RTD6DtvfBmGZ0QiMohvR1AU24WI6jsliHzGKGPBs6Y1q12ioA+yCQnSVDjvpFcYo1kobmmb4W8FqxH0iGG1QbCPwO3ztdFC6lmaRc2yTXwqfU59Fn+wCcVyMquE8MV3B1U4X+3iLQDJruvcULav4QYb9VY/6HR2PW2AmTGsn8YRWjgJWaJDyQjGGWph6GCZPJBjZ/sNtAg7H4uUze7pLR0UW1GIxR0skhYRsISQnNz90FXoxbN9cfxSNNYzaFts4tEXwjFEO9tkBtyFo+4BSobkXyvkBlh5ppNLhyP2YKlcwAXs4FYdJAzm8c1W6VTmRx0WqsMRWzVCCzF2rrCcvBw5IYOgPC8VlhbMzyZszUOzRcudn0Gibw=","layer_level":2},{"id":"2dd530f9-b2f2-4f38-8cfe-817746425a39","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Offer Input \u0026 Management","description":"offer-input-management","prompt":"Create detailed documentation for the offer input and management system. Document how users can add new job offers, edit existing offers, and manage offer data through the OffersPage component. Explain the form fields for compensation details, benefits, requirements, and other offer attributes. Include examples of offer data structure, validation rules, and user interaction patterns. Document the CRUD operations for offers and how data is stored and retrieved.","parent_id":"e847f4d2-fffd-4700-bb10-98246cdd7d76","progress_status":"completed","dependent_files":"src/components/OffersPage.jsx","gmt_create":"2026-07-23T01:22:12.6853503+08:00","gmt_modified":"2026-07-23T01:31:42.2770462+08:00","raw_data":"WikiEncrypted:uoSe+almcPogJWIumMMrX9ROFINKQk7HoDiUIKqrq5dWYeKe/5hi3Rbd0+As+yCSrumZ3ivA+YS024lQT7UldJUL4BZs9o5aZNtFp16Ed8Uv7BCqegUPjAcb8Hw8VihXULaufN4Pl5TpbTFf06KtQKiw7Ap9niBsR1CKz8JG2yzUU0Ythk+CLdv4cNPxaOmXrtD5Xkp+KauQQkwXfNOiN6lCroDC284bSXYeRrEkkPB64ZUJpD+mweJzRMR11z+CgXuI79+vsn+yPMPbhIN8/wWo/Iu8qAdJNjZ2iQ9+uiyhdGfiY8i2OHbU3ffWT3yLU5GQ4ZdTKM9kYsre3vk5gIcXal82FtX88BEPPPeZGxl8iPvV6iYwkcFk4YJaSrTHtyp3yEwHrQr9rAl6hhsa70fsg9exJpV9zYXnevqUh1Sbgr1Ci5/0zFUf06DdwaGIipe+3y1ovWIYCbw+m6mwsq3gbrWuxZj5j/baHEfVRV+9MfN2oAfj2AWl7vicD4FvJPCCPF+aOBTptIwl+msDAhaC/w5iKg2iKHCVTNNvS25id5rLKJsQ/IkW/Xdilc7iv8iF5WD/4vFDzC5KleYDESxYc3b3TZI9hMzx1VesNAq9On5zSMKnweP9ZjXIB5RPpeSLcezMPXyWfOBP8xb7DqXz1+5zRegC47kuqNOpTmcMgrORFsRbGlXW/3z+v5fJA2b5cSjRxXD0+eYHhd7u3hOWoPA71AbGhbhprgKJGq40Srp/sIV7JDhtdmq3DfxeNkWj6Vd4eSdMn04JIdbVm/4jzSMNWkq7eSKg9m7XSdm/ac2UfxwLwuvj1nAUziD0IjOEAWm2MRQnKEPm+vlpzbj1hmTYRBr9ija4UTe1+uneoO9DZjWYlbYibT9wy8akRYZqNDJdAvCqJ828p+kUYLJC9jsvFkDqGu67zB2vM5Urh/L3VZ9Omu16mUzAcgPDx/x5Sy0sJVZenhGDGXzbqgCXzAy/uI7jYbsR4VK63wTPWjFq2t1mIkGHEcBeLb/P0b3pxgXJCRASVdLCGpCBp9CpCGGJGf0IZdlEidNEvrZ8y6CiSLaTN56Jfeqya44l1kwgK438hh06vhX6s5RVVVjdyhNitiTNF2mj7LHVE46mH8uNURv4uCDqlWXQ1/JuDwoAJ9PP4e5uLcZD2/Vksg==","layer_level":2},{"id":"714b137d-5a15-45ec-830a-e5788683db3f","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Context Store Architecture","description":"context-store","prompt":"Create comprehensive documentation for the context-based state management system in ApplyGuard PH. Detail the global store structure, context provider implementation, and how components access and update state through React Context API. Document the store initialization process, state shape organization, and performance optimization techniques like selective re-renders. Include examples of creating custom hooks for state access, handling complex state updates, and maintaining state consistency across the application.","parent_id":"15e41105-5f69-496c-a0c6-d162881bc0aa","progress_status":"completed","dependent_files":"src/store.jsx","gmt_create":"2026-07-23T01:22:12.9632777+08:00","gmt_modified":"2026-07-23T01:31:46.0966534+08:00","raw_data":"WikiEncrypted:qiOE1k1TA+YNTXi1/8EeGo55PH/jKR/xA1aRJ418hpN2P8Hf5LOurOj/MjbGyvw+YAhhjrM5w7HH5EbHeNyhLKFcsQY8S12HOx/9XVr6YD9aoT9rWPJJej4mB86JqiwBBvOXB4sdZKgVR+qgjUfX7cR7iwT1JZU4PCNKP33STebUX9qcXzq7LS+xMjNK8atE0TN1x4Rwr8uM99WfBWj9/CBYn8AXVM1EhlneVl8YjJiFSj4vptNAX47+biGby+lio5s6gz6NEFEZ90X2Yt+Yu0nz7yRa6rMgHMUqGiu4cHIiS/LFFwdaithFrqmvQ+1crOp12FeYDSDBAqPd9mSmib/Gnt+cgsGW4I1Z0dCOWoABT/RatmrdGuL6XqnQOT6+0VpKZPuJvvjfZTx/4EYfejtuRWM+nB89WJJwYS/JVlRQBGThcw1tUJaJYOSRpmWfdgNG383kYe1CE85BMOcrxxtep5uBRk7GN1b2LItOOt/1tGethn5Dtm8RgbUVjzlLOKpr/QoPuJDLK2O2+CWnJj5vFtW3jpc2bZt+9QR52uuTT8mm4riwhfx6GZLjHYNAx6SBES5E65DxyGVRZ+/9oOANmxP7vkEFh18Qww7iEWXLUYSZOITrkHXheZy2mivFiRO5kSTsKrx+O26qeR4LkzkILVWX8DlgS8BYWAFA36RMgGlV5l9HnM0hrbAzvS2yYlURaro/8q8dVyMsjSFZ/XbRpswpKT4FoEBh96rwJqkaxXUggw0b/ydsebIxlgrX/iYsBGETiHy/k51ZiyjO/L03W9VF+rMJNZCZo3U6gw7uHlIS/DIvIITAdYWHq9WD1WisW+mP/sbZ5TtgYxs3tbry8y99O3w5LxfJNxGhY/K9QenSGKsnjwX40hCa1RUOEC1L6ljxJwSUJPaPS2oiToEEskJ6GeTWOEF4Ntx4otCYLisHAMTxUaREIr9miYzg7Ih/LOWltYifAFEa2K/XICTd09oJEUijAwGvdjdEzh6DGexAV8D+pvUuIT6Ps7+06M3ekOW1saedk83fyFhp4MFGjwtUZrgpoK4GpkmQQss=","layer_level":2},{"id":"1be16ede-7e29-4d0a-92a4-afc8e48d3725","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Layout Components","description":"layout-components","prompt":"Create detailed documentation for the Layout components in ApplyGuard PH. Document the main Layout component that serves as the primary wrapper for all application pages, including its structure, navigation integration, and responsive design patterns. Explain how the Layout component manages global state, handles routing, and provides consistent UI patterns across the application. Include examples of how child components are rendered within the layout, navigation menu implementation, and mobile-responsive behavior. Document any context providers or state management hooks used within the layout.","parent_id":"4e6884c3-ec96-4738-b40c-ddece5a2a3a8","progress_status":"completed","dependent_files":"src/components/Layout.jsx,src/App.jsx","gmt_create":"2026-07-23T01:22:13.6905118+08:00","gmt_modified":"2026-07-23T01:32:16.3934438+08:00","raw_data":"WikiEncrypted:x3LcpLCzT0KOPxd1xeYY3c7iq48qz+WPAPm3x7MWgVmMN2ZlOrEZdaRXZxaYKQQDsUQUaZVmttBkOliYwU4AUPu7K+eajHQg+SGNL4CrXvXphLtgA8VqEibBLdr4h7PtjhV8YZXkyFMqS4w6DaCfJE478BR1O2qbi4QVtKJl67u/TpYEaBFbwn72Rj7PCpBBvs/HR7mVmmtQvEJuWHuFdaUcSUxFFH0d1L71UE6E/98xq7Yu2UF8Oa1GCLh0exyzVxTQZhsVPRa5aTQTb6S2NsXwJtQiPVc0IowKIDXPI8h3tzEPB8BZTSQJA83bNLuYAnF2/jmgBNTsr/wE6cOuj0NIV/ccYQ7EGz9oj756qaLs5cnLYVJNIOcOosHDcet+Wi5cokv9BLyhkYtJmb5Y3NUjz2zIl8sYYN2Y5Z1Q4Q+QINZlgRjW9P3fJ+QbLJLQ8o7eaD5w4t6Z8jjL3K1pkYopQntBUdePtIfQbm1oGaIDMa45ODtxgMd1PYR7Fw/ip6CKcmheYwBnIcwWjotjI5+xoCVGto8vCdeNTtUdoQwgCLK1Ds888agIZHHnKqrgn9sawXq9Ebwn/qHC0vlsGJJJALq7x7uvfoBpRAWtBpjPmEANLA+elCH59vaZdkpkKoaF7FcpZH6UZn/pI90qKUt/GGG3MYcTgQcARYIlvqDW/RUpCO8BJSrU9bddNJ8Im8lsoAGfyBw+bJC2PSxYXVJh0oSxkcUu03ksbQyBFCGALrPTCoBDpVPWCb52PWXl6OjKGNvHG81XHRkSDXIHOzrDErScS9P7tw11eD1mphWwz93zsdm0QNqMulEZgS1XcOI7yw/tgqBMRIk57wi8oOOcRRepTnIl/f7Xrkr58FUqa+PVRI+8s3MC4LBaUiEYiRks9q4crtTnhi36I71TRxiOfqEvWBH1OaJn0ZZYfQzblcDUdkEhsF4fSWOlWcJSfxFDgFu71CupcV9FzUVlX3oE+bTdkJfer9+GNkfpUf+m4kbg6jhhcHNQgQm6e/ZmOmzTkKMf3fmSEYbyoIlexKWcrmJmix1E/VeHAe6gesG15GfG4atsTueJoxWohVlqaH3arahzTEfwsLskQ8DUgFgsSwHljXLwHZTDc5qG+YgG8BX/smv8R+B5EvTQSqLbFpr4LA3u7SnLFB0sBKRdMji8aZL3RmyteEphN24gya9sb6dGF+E5T0J57KlIN3X/u0NDbZyV3sZHBJApkIfgn2b0tMJfZoEOIun8CxWx+tneNcDJrHRR1whzbBlJshPkay1pvMsTn9u+BfoyJ/wcpQ==","layer_level":2},{"id":"80cd19aa-ad84-4b1b-b83a-8a34a7c03774","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Component System","description":"component-system","prompt":"Create detailed documentation for the React component system. Document the component hierarchy, props interfaces, state management patterns, and lifecycle methods. Explain the reusable component architecture including Layout, ScanForm, ResultView, Toast, and Settings components. Include component composition patterns, event handling, and prop validation. Provide usage examples with code snippets demonstrating proper component integration and customization options.","parent_id":"bea14602-7013-4ae9-a2ec-8f0c2eb62a02","progress_status":"completed","dependent_files":"src/components/Layout.jsx,src/components/ScanForm.jsx,src/components/ResultView.jsx,src/components/Toast.jsx,src/components/Settings.jsx","gmt_create":"2026-07-23T01:22:19.1399426+08:00","gmt_modified":"2026-07-23T01:32:17.382137+08:00","raw_data":"WikiEncrypted:4Zqjl5aZEo1Vv5NKBpebTqt3sxXxOtzcMOpXIMlVq/QUqZDQSUf/+ygZOoXWrSyqZNBedKPHqb22YMOY3BuOc88kS8JQKhI7oLYnP+zUQNj8T3sZwvJ+IPNIENG9q/6EN6AYDg9hY62R02IzeVQQWhekdrtt9Bdh9geokW/EhlkZQwusqQfATru0wE7sgoZmU/v5eL3ukYXqCVijKwaBmpwaI0Cv9xo6j+h3cM/eAowJ74GQJWYGkVWk8jNYHWC+dw2IaIzYB/bQbbhx+R7vE6sGy8OvQex2lBwXTcd4ILih/C68kNquTj6Lm3ktyPiiSSCq/HiktLmTbpIza2jP+N+TorJ2iq4uKLGXqTxVrlZ5VVEiayM8vPUVyQ5dK8KNr/o8CIpEZjlAD9cU7gyqtEQ5BwzgD5bDvl6gChNueJD28TYSG5WKt+1a8C3ukymmTTXQo3ppJBOOMNdfaeATqflcIwKhv1hhXSN4I+Kq5jVl6wPtXEWhix2jR3twP1ndXIeqiywMQ6u5EOaDdvdXfXkZ8zsI6jj6kLFvE9+Yvmt7lJsKVLwXjQle48vyAkE3tUPyVZGrQtwZj8obHAWXoynapSKFJmiNAAp0ShU/CBN+HTSL1F3Y6pJeOcyT9E2ZtzIUDlezpuGKyFCbgSnlyyCT9BkcLV5pM/YD6xVnJK+6FGRj7/xQMhTSuRJjRgSKwqbfIZ6PGFl7KvnoY/Q4PzT5o0O1lcPnLEA8IuT6yiyIw+3lzsvhDWGCvMZAlOiIlPoueyxdLrqswxo/mOIytJEHjE/f39H9qZQbt78dXmzAaqVSUG1kAGhOjLWxZDVKuasuaHBCVG8hKT6U8oeDwTFTE8ogvqT0ehdI+QgFOMK1mSZqgaCWxCBTxZWT528bU4jEItK5P3ufkMeb7jmMzIaulLWZhCUU6CZuYesndZNBIvbJX9hZKcWmqCnlbAMM5RbSZuoezMIA4y5CBpZ6OMM9x7iELk7V9+DXRG4Vz+XTWpaLzAGHAOUeiFq+hVQLN3zRQ8+D+x0i4qf4T8QWxmLmODd0jc1dYg93uip2DtXSq2rrM6xMU64CNbHzCIIFw5txWKQ5L1r/5o0jmjEMZiU1YPqxefG4W50s9gkMfTJyV7BpAvH71FQ1q+t0yGbTXsfTEqRY64UTVjvYFALLO59aUN2MbuBPsqXZgxdqyxEPw1K+fQ0uvWTE7rYAf3EfnNZKS1gug7+e7G49f4U6UDMtOjC9VKCfGhIaUs88iK2aBwtljirzTPfthS/Z7yFejMCh63ZyY6nX2qpRYjx4TIUEhmxp1ozM1YGbjsLIS6Z7/9x2ry/rrb07wMpvcbzu","layer_level":2},{"id":"ae6aa76c-b442-42b8-8ca1-b2688bab85b8","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Edge Functions","description":"edge-functions","prompt":"Create comprehensive documentation for the Supabase Edge Functions architecture. Document each serverless function's purpose, request/response formats, and integration patterns. Detail the AI proxy function for resume analysis, checkout creation functions for payment processing, webhook handlers for PayMongo and PayPal integrations, and utility functions for data export. Include authentication middleware implementation, error handling strategies, rate limiting approaches, and security considerations. Provide code examples showing function invocation patterns, parameter validation, and response formatting.","parent_id":"b9cbb862-07a3-4429-bb2b-1691865594e0","progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts,supabase/functions/download-message-pack/index.ts,supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:22:22.8311242+08:00","gmt_modified":"2026-07-23T01:32:11.1371858+08:00","raw_data":"WikiEncrypted:UKlunF/mHL6mryERVz9Q8ESmyAi2jlsEFmS8Q0cw1ujz3owxiAZNu0hCdL8euKQL5U0Trc61uWBjrpE3SlIaoDMd8locfo4yT8J9HoVjuWiKUQjQ35rXqeln6lD2gPXac2Z0mE2C8B9TwlKi2H9v2G/hYcQuIlT5DbUgCL8iLnbh0kAAZfywQmuZ/26Jrqdiz7PTc6E/jv6WqIikJ5mHHR/KC1wV23GyhUI2Ln4VzGXQmCIQZss419Ge4NrDq70WqTVSVsRmU/qp//+7hShAovVhFsVBtQRaKhXtctPOA/AI9BDdNUt+sLdEpBUnKbEqy2K4apJhwqfVpTCyov/aR7OuqEeMNkGRNt9Af3Y4Aq108r4b30hJ/9VQsCBcO3h2pKOI3+O6OViUQGCqXRktBL94IFaXVTxaU5kolKDHjo0TBrTl/K9fcYhaSk9vLqV/t12cHUWKGZcWGX9TB+V+ghBxumOPLL8JFxfBQT56i5tT0uZvp1mtGIgEt0T7Z3Yd7ig8hPyIhLXdCTcmxknJm499xtElOzmBXk3veGXgb70meUCmDkvG6GBZC5pw8Tgq4YnCpCSkK6Wrv5HtvVYvCNT2dB3gIp0MMjAb4CWEg17eAHddLkmWjuPFrP4bdN3fAhcr9r3R4dPzcm8Nl1XlNf9whvE6YUOfURmrZyq4eYW1nWCbzN2laznyjRMkHtAyvANV8sKvcenlamVW6Cqf5lT9Cxc1aeRQVO1ySCztJ17f26snlOC9oKEnerTaQhGzrmmlR6Ce8uuf2T0aOcqr6RcD57hQye396TnALww+Z8Y9VxPiVyC5T7iZ9LWxzBzhmqM/JgB1drsc7jG6GqGYGfMLLIl7/xwjeFFY1jSiamqbYzkws7QZQXfTQ0wJMAaMF/TaTp3lTjPWoe0iIk9ORFGLH5TxgGP7ey+j0IK60+SiWeADP/vsQ3WGVaDWwl/XHde0exzBnc6J9qCaAsyDpoHIVEt6qy2coWlaSE9C/rGDNhssD2OEXcQZ3fUitnNiEsFDL0wEHA0pg5M4/sk9jVxHfJdIG31cjYy/JuSZ1WVklEz0WeADpK/5XTIcekGI+JmIs+WvPaPqRZQSpWO4x7E7Bs1MH3Tq93R8CqH0NtiUZ8BPbHuQgqmhGi+IwyiSVeQUNGIrbtHLBEfDhOLJLDUXjXkii+HCTNvWGFKC0sao2FI5pEUHL2C4j5DYgH90ic9e7+o83o07U8IB+UKqRV4a0ukArYtRyhIjlspKIFpj0kL4taNZR4Swa8mk2cFhTGdwDLp87gTzX/kW8sn9MopMSdFlRgseMgXu7ezKto3R7/WzOg7hgWuxzrIH/HL5ndcaPw7SXe+kn/4wWK5oEmo9ErGNAVp8iRV4mzMA4f6JMtROXYMN3+vXCoqNto/v2mJiPFYc1fzum/NKhOKBI8bLQjX6fDgF7SmsqlIKqpKoJr+2m95Id862bnz1VMPgfrhemXYVcFOCqSMldFZBDafxvoxQqY57D7U+dHaZwFLRNnW8uO1CY9ftIyADkH9UuhcXhA8RWpLIhVgHuH2bgFckCPQxxGzHtII+1Yi9LcG5pcZh0cNCa7LQwu4t/xF0X+Nsj7QlJwy2Q0oDONkad/hIu8cqspKCL2gLOPorrxlQC+qfX9cZUtIewLIZxDX0T0YrG36+d1mVuJmemMkGBE/KsSs2FeMQ4I1PSbSSQOk=","layer_level":2},{"id":"1896df7c-d615-4342-be7b-ec84ad9701c3","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Scoring Algorithms","description":"scoring-algorithms","prompt":"Create comprehensive documentation for the scoring algorithms in ApplyGuard PH. Detail the mathematical models used to calculate application scores, including weighting systems for different evaluation criteria such as experience match, skill alignment, company fit, and job requirements. Document the scoring formulas, threshold values, and normalization techniques used to ensure fair comparisons across diverse job applications. Explain how different factors contribute to the overall score, including bonus points for strong matches and penalty deductions for gaps. Include examples of score calculations for various scenarios and explain how users can interpret and customize scoring parameters.","parent_id":"807ef1ee-e7d0-4485-9b75-741a4a80cfab","progress_status":"completed","dependent_files":"src/lib/scoring.js","gmt_create":"2026-07-23T01:22:25.9836176+08:00","gmt_modified":"2026-07-23T01:32:48.9462348+08:00","raw_data":"WikiEncrypted:XB3PgRmgb5x8Psg1PAXkgQj3YytcipQZBqLncX1SOzXhtDGQh+dlG4/q6xAjDe/hCULDFOojrKuEZ08CI9CkNOjw0eyn+p1uDnIqW5IGLC3cw7/JY+C8KJDGu7yYsedY/yqAon3wPhrtxJiI8YisLDo8X75ffTX6Kl9W3gcEC6dinB9wMZFD4CpS32QofaEllVlyQqhW8MaKolycNINZQjQIsiKYapt1Pa6ikc5HeCBDYYADDUxbbaaeebbrQsCB/a3JVxSrXJ9GVXgWSxs/cbaJ1IqG4MiTYI5II9iMfTQD2hA+TNDv+ZWfJsWyBUSqPkRjBfgAyEZ9v35QDYFOAYz4G68wEbg1KGCw8TGAETScZnayrYfpvkzW3mS/QYhEzfzJfe7RQ/Ov5OysCndOUT8GyWtx/xIRMkreo/L1PYNG04zf4qVe0UG7j9ICkMtUincxTtWwT2pAI75Awvv87MUiR1ZwZ4vI1uXPXzGu7dbrJrzYmcMnTLcOBDXrQdvS+H0Y2kvTYW1r7uLqQ5NOpZoMXEOeIKBfcf6xQgJRwruC66EeXKXT4/e3tJR0XRTyo+inLNdtq2iLU4ZCHcuftBzJIqclVpmI+36oMwamH94XLCRD+8fJYwiGIvPapqB4T5grOEfMmwIDO9fPPNzxN/DRKXBCUSIzWakDHojgAHTzzt8WaU6815/+sHxR3n45fxT5YEI+7idlOFTrUWBGmOLoDodtj4R1NE80mq2BS0rxV0TMaHiy1XmJ5hCdQZyzNWx4Msj4WgIAYdX/6xzVI6W3r/nu80y7m2DvIFO+pn00YtQGCT95l3UZVHQa+lywWv7AT4ScSjBulj0NhhXt9uKUbXALixtzUreZ7jR+YTz1eXL42T1hDLnc466qIKavrK+1i9ltLwRyP1i6dZzh9uba0yGvO1vu0QHl4JPCsH0NNRuok+RMZl8W2mNv28IvoCd1/EDiXLMm6/zjwYKS1cBD8S+7kxsnqsMWkcta8DqIxk8giOBSdchH/w8Ii/uPHv7yryjX3zTBrp/NMr+kbkaGpqU3zEU7+QgcDEowEnZxjQhItMNHWHlW5ZF5TFoWT8Jnx3MD9MLPhZKbtBjL3BAxC5KITMtPxCzeFBkP6EYTr/Ezlq3hwVnQxPDsPwnase77mVXUSTrEREl6thPQL6JD9JbEFCmoutg+nE3+7rBPz+KzILbu+SB88RJGmIG/IpB5yoBN93Ru7z5bk85MgQmppu999aBjhcw0DWWxGUqI+SGW4KsHVqy/fdxcX+hQ8noIDxnDJEdIKYGk8MCvi6mZgtXwGm0Hdw8xmfmOaJvzYRyxuxC7Q3cIqR6VMJM5MoBdkSiyN6ILvO6p+6riIuhdkdW6tipGKZvEjDV3NPHUCOX2AZZX5Hh6pUlWEQKr0eZ948gge0kimCV0c2SGgmor3UzUzxOTau17EaMRXB9JYmUm/XjRbWX5xynPeorPR7yDBj74YNBqjOdcgcSQQg==","layer_level":2},{"id":"9a220833-59ad-4f85-b97a-3c86cb66f887","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"AI Integration System","description":"ai-integration-system","prompt":"Create detailed documentation for the AI integration system in ApplyGuard PH. Document how the frontend communicates with Supabase Edge Functions for AI processing, including the proxy architecture and request/response handling. Explain the prompt engineering strategies used for resume analysis, interview preparation, and content evaluation. Detail the error handling patterns, retry mechanisms, and fallback strategies when AI services are unavailable. Include examples of prompt templates, response parsing logic, and configuration options for different AI models or providers.","parent_id":"6dc96b36-07c7-4466-bd10-1f0ab817577a","progress_status":"completed","dependent_files":"src/lib/ai.js,supabase/functions/ai-proxy/index.ts,supabase/functions/_shared/prompts.ts","gmt_create":"2026-07-23T01:22:26.1366278+08:00","gmt_modified":"2026-07-23T01:32:49.1204222+08:00","raw_data":"WikiEncrypted:cziBIEQqiXGL3msY0WwrlhUuk4GaGam6ctF0hVICR5Pw+29pls0ggVio8Vi7cdlhx4+RfVrVOKnBMZCY1uX/WLYRYqwKa6ugUJlk9KajYXC5da+wZupR4yBEE8qSC/MBrGyORacwYJH9mWTsuSVtlOkSbHkWBKbvUPuvZQvab1QD+PnlryjzBgy6q4RHwbfWlpvhxTFRF5xce2mYdI6Ju8GSUWYrqvXlTe8K0WGWXM4DLo3J1a6X9s8VZwn/T4b0wC3GEeAswwY+QesbREAv96656OFrtgz00E8I5i39Jr2hm9CYOg35XQ9ShQeMpdBXQ6kWr0bmwoRK4hox/jlnHfz/NxiEdzE18c72R9kEZehOL7ynXXgsp4XsUDFv9qOQRyP1GFOI9bnc5qXCyibZorwU1WO1kItZBtusBARX4YirIw+DBrjv1K5lzmssI3SGgZkd2KsHxv+elJaII5VWbArwy0HXzBOixNvN26sX5Onkm02C7Y3oNZn+Ec1ow0dcXfTzPUXE+K/YB0a2zLjFZCbBJNbwi92Teo08tyQFJhIBYs8Rwtjg0j5UGH1qBTa/RY5dotWqsLqDLRmlGyTEkgBD0Mm4n7J9xVEhI5TYLFyk/0A2MMSHoZtxl3GgzHeFxsGjxhea/h458bw0S5q21OLf9ujdes2liDNqsILbDKh97jUegXqm3Dht+G8It32una5eeKPYiQxElEA2Xj7m0wbE2/fPX0bkzsfWrZX4l567pTUNTUAthbH92SnYwDJr2IlqHyn1g2ZO/dnETGBtapPukYgI71QfeMySAarFeJ5mpNGkmR0RH2P2cB1jJFDA77TYHFuFO34+4TSVspf2WSWtT1j0bOGOIyNG0qYSLixOV4l7wfVVm6c569eGj4r88Bml50ykNDusO+6X/+e1k5n+Ptjay+CxqOXgvavUydN18VeVWaE3aV0njG5QzrULPh2F+SaLGyuDe2C6t/zFXeyaHzQl1ZrwHx9bHp8SnpqUS6PwvcbJtNytWpItocrKkn6otRKBzISTwXpSWr0sc913fKcq/QeWtLBJa1rfP2wies7GxN13alrPPTjZQruo4dFV7m1ItCtFa6A2WhMhcu8hOt6OPeYZfOPYc4fih2z4iIs7CmVwJX82rCqa0h2eOPhjwxtmUJiXqc1Grgr/ka6cMKRwfm1+9KWwJ/JydtBT0rHRo1YTH5rLT6Ew3Z/jGwrp107yHVwgqideEhfCwPgBQzWmqiKHwGeOfab+Ka4/p8YKA7Kdc7HNVm7c2TRhIgIBwsjgaSxTrLQ8ZQqoHV/Ia/m3qsuG631hvFqYftDF0NSNGOYbhg8qiCKRpY4SwRiXcQY9ifBFIj1sFi6HqqSh2Lh6vdiojfiUhsKnJqKdJ9fUREXGxb1mn9tkQBcFcBc+C1JnXilN8F1nyEioAA==","layer_level":2},{"id":"3095f9d4-3ac4-4530-8202-b3489db7e21f","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayMongo Integration","description":"paymongo-integration","prompt":"Create comprehensive documentation for PayMongo payment processor integration. Detail the checkout creation flow, payment method handling, and webhook event processing. Document the create-checkout function implementation including request/response schemas, error handling, and transaction state management. Explain webhook endpoint configuration, event validation, signature verification, and idempotency patterns. Include provider-specific API calls, configuration requirements, security considerations for payment data, and troubleshooting common integration issues.","parent_id":"66e799e0-8dd6-4668-ac43-a4bd7c42a5eb","progress_status":"completed","dependent_files":"supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts","gmt_create":"2026-07-23T01:22:27.4658881+08:00","gmt_modified":"2026-07-23T01:32:55.3003546+08:00","raw_data":"WikiEncrypted:cX4Cq6ycqUrOaFkgcmNdX9dgI4ri1kzZnPZSNzpDBe9pYPHXD2Lp+l1Ma1HFbAYAD+bmk7CKukPxcILnz/1xaiw6SmAmnVDA/DXgNjlBdHzOM6NSyHVxMH0aZFPtwzXupKde7L+AR8INlCKD7SFvjJ9p4F4ZVQe50ydpsrK4kWNmqWvMkQTn6nIGg6tmEnrzxD2daDx3r1xaz4KXeBcsCTnOlyFa0KyAFFnsU3gKzNrnCN3Y8vf3dUYEiZU8YYuRW4rnFV0tNwk+zIfdUKMpeWVHqe3DFGqnODuNugAbzXfqL3m/EspPgMDEjiLF06ite0d0kBDbgwpUvmFqTeL2VuRrtxHF+9iRwnb2a2YxpGmbRvFR+LaxL/kCKFP2JRhuoUbdAhPwI4rHKXCT0eLT5VyuKFycwSdByOuI78NqrtcV4BE8WJPLgHToAwHes/ZVofw4+l6bQBa/iUpb3C5w5XAU03scSCKTLa/AYT3J9TGm1/QdcRIHEm7HNc2gHykcEqAGbEd89Cci1bYFywyJ4RQJvyGPNGbdR0gFt+91cd7va0ebWKejnwXVWiGBJzgpH8cWr/+GmjATLNS1um6uT5xDKygQ7Elln6uj16pOipr0NuFTWEJJeGMuqEiQ2+U6kOlEm464TnZ6YpVAshK+UHWYp/LKD2y5CDTWDFSzcvE5P0BYPc6U5EchScQGcjFCPzi9pAyW/NjC+ekQw6uKxWIErPI4M9kJl7Xsvk1Bj7sNrT7VGSQDFH3cTAs5qc5M9/pKB1oizzDzY2oamB1rHfP0mZJtlW2CGI7VMDikJxb1wsmsZNswO1fDhbPSBVCcoco5rrRMOOzP8O0bBzEn71UlmIW4Rt+9aLFNtAuv9vatEFargP4yTEUdw8MM5E/7V9jF6r7AqENilHKZCPeV9lqKvrTR39PbFWoaWNPTHE/qnUvB4qBW1x2iYyWBV19kH54JIfDqnRld4lV1ksx0twqJKxmbehGW/FKZ+kHcQynnAlbmurUa5wfLaKDxqB2bF1Y0UQWF/nm86UHws3oF92IYARUWrRPyutEcw8KPngHhSmaubjFv0bx8tKoHNLoGGE2axtetiRfhMAjOb8zSboyMqTAiIx6QeuGtTQXVRN3Qv1q8le/hQ11rIkRtZU4Yi8XHavH0FeWl2VhpSHTZn03KXBdVXrhzd61iy48Iv+aJ6wxPJsl6tDgO5q5WQ7ebe/gDi2Q8n7g1f5/OHmN4lfc9lxmSMw3FbrGttoaez6C34dmQ9zBBWjWIq3yVPKMdVLI3DBe0WpmfDLIAeR5zOsqusqc1XbCsxp0aaQc+KW8=","layer_level":2},{"id":"13f698e3-d6b3-4d3c-b622-6159b3f54a91","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"AI Proxy Function","description":"ai-proxy-function","prompt":"Create detailed documentation for the AI proxy function that handles resume analysis and interview coaching requests. Document the API endpoint, request/response schemas, authentication requirements, and error handling patterns. Explain how the function proxies requests to external AI services, manages API keys securely, and processes responses back to the frontend. Include examples of calling the function from React components, handling streaming responses if applicable, and implementing retry logic for failed requests. Document rate limiting, input validation, and security considerations for protecting AI service credentials.","parent_id":"45127b67-19f5-42b0-b44e-63fd3d377aae","progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts","gmt_create":"2026-07-23T01:22:31.9822976+08:00","gmt_modified":"2026-07-23T01:33:14.1715631+08:00","raw_data":"WikiEncrypted:jLB9r4y2lG8K6C9DNsjHlIs4lyIhyotdJSuP/oFL8fkip32jbL/JsgFm2I7LOsSQUkFMxq+rmxcVem8v7uEq9G4hSzUaUB8JYFab8OiTMxJU8P8GTsBeRNOekkmNkXVg5l30zsY8yk13pJuMt5fXYChNltnpWqSl6L/NIxcc0xtt3fceE2chcJJ0rio1Zzwa9SWsDn4S9r3XhN6++jIXFd7vVo9RggNB4JRm5lPg/MF6pFqySMTXDMQ2voq2rS85dYvJSq4V0q3BPshatE0ey/mQbbq8hGGQNdDtg6bXGFu/h70hd7rlFKMmg9yqe5SsDrVU55oBgOZtolSpfem+Nic84H5qvGW0OYPOA9zoxCCzNcAy14YP+5XsSp6EtEig0e9EgrAikAJ12070XonieBT9p+E5u4zO83hCY7yPJiXT0EU6f9BRy41G/iJ9ih2FWx523453siwNeWk2rwak4ryWuUVJ//ViuWLtqS61jtYf27l9MZx1aEFr+mTRvN1ZSCEHbqKMhzqdzj2AKr3R2RfiNOcHcQLG0R0qkKuJhoOauLobFnS2FOiibhEjU9qn9Ncy5LF9T1Cr6GNSYvMZkpPx5u9sERiu9APQL7BFpkAV24IpPBuph0vM3KrX8747Z88ZZ5sdAfdL6XxYiAL+7b/DDMWUQhikB9CQPY6TIqNm/Sbrb5CNvD0eziUXuwaEzwyDfolpsmdaUFW8jpC7gj7PgPnvUz5swh6SFH06fbeVteWyyYLyc7Db2SCKc8vevuxvrxbKqMobBAzJmISMfV5v7AKgmhegkMFEBLrzg8/B79ipXoT3NlyRJ5hotlSitW3JuLNNHcqVwZfRSX5RmjSt6GTiGJuKn2dPQM0qUwxesMhnwVWnnJ1jL7zgdRL517eJMjcMcBS2uyW3ZN1voreqh9ZeF5p3ShvRT3L+q/q/mKLZqAvCSGigiewmRxc3VLNmmm/PrjqG9gL2rBTLXngZR2bT52CdYZFCNFm9+BBKfKazHP5uIVtBqGyysSrtqV86L6IJ4YVPWd05AwpAaz2jkT52H1qfemiuUUSVbac6Nnmbah84nw/6RC+t/0Tb1+Vnh6M041q3HgoCJgt1RRtBu3IjwIva3cWaRSzB7BJdXwWKp0ylq6ZY4891yhV7pE7cQrmMWxrVHKO9AQbIN/kWlkuBt7yGfG4r/IGGB0lMTM5IKETUGVlLzh/5mBhHiz/JTMzEAa7dKsg60SCJsk7Gt5mYW1pudHoveimxCM0=","layer_level":2},{"id":"45669aaa-6053-4fd6-8ec6-372d9b88b0ae","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Status Pipeline Management","description":"status-pipeline-management","prompt":"Create detailed documentation for the status pipeline management system. Document the predefined status workflow (applied, screening, interview, offer, rejected, etc.), custom status creation and configuration. Explain status transition rules, validation constraints, and visual indicators including color coding and progress tracking. Include examples of status change operations, bulk status updates, and integration with the tracker interface.","parent_id":"7da1925e-ce69-4e08-85b7-74f2aa2c5b88","progress_status":"completed","dependent_files":"src/components/Tracker.jsx,src/lib/followups.js","gmt_create":"2026-07-23T01:22:36.309802+08:00","gmt_modified":"2026-07-23T01:40:05.7350372+08:00","raw_data":"WikiEncrypted:RIfdD6bOTCP6I5SHLW9yzKLUFkv+unQcLq6dxDrmS3RSqHd4swY/HfKpgLOB2kBsswyYI7CnEa3mHZpChtsLPzyINLaIYUF2kKUrPAjprZDH7FaR5BfA/rNV/GSE0f8za2Kh0OXFXWD4fNb8cgdkri6cNCKdbqW5FTn01V5cSywB6H8G1PKxgzIpSewgYQajJGRx0f2iazI263mY7j9NzictAgtPobH2v2JohpHTskGPMd9sSdWaEnrdRBVOiPOkLc6Is9qb963MJTeUh80dA7Fw7LsXv9gWQJ2gYUhQAHvcV7gXKWsV+63RTkGngvbNTuBmEtQRJAZRAVFaGmTLwJFG4OeGrNGkR34n+DBHetkqUkNJT7OMftJPOBr+t+PCDWGTsZ8D2CRA1Hx09NrlsKEEr1n9+FyG77l/0/Pc4bbDXI+KhkjGYWnp/KsEX7V2fx8rsb6lsP2IQwsAZ13uojvqks3dIigwVmvuBZV3ZrihhkSQKNwZ9CR9Y14BANwNFfrErs3QFxQMf7W4+ZihVF3T1t+/BQcAd4BtBjgivRXGdWq4NrrRw9TqkpJJO/AekfyDvOZEOnafc0HVgZQYBbAeHLepRStGn3G5bF+Bti1/UAlWFMgPMkw2bWWo+12xBUsnVSI8aQw8xu7fHRImtgeVRkYEcj7/j+X7CA41tKZjL3MVESLf1NuiTFM71O7H1H6LdkMFHq8VUJDh+gQI+zplBsNxCup0qetvgQQ7ek/xQkPW5f3GTdIRBeMbobZLh6bZnTvdx2qkskby2PwoqfHqgvQ//g5IpEupEJzsbeXrCsgcmF5OLfYGWV9jvFxmnSxxKm1ANC3kuCMQuMl6gYF8lR3xQt5VnHSLd5LqdAaFQ4w/Z3h/6uG/M3nrcuTe7L+JHiXkqr8phZgr2sWMeUPCGHL8ShG/XSwPN2KrWbCPb7LjZZoOrxFGvdM+v47z589fV4+SLKkXtcJecE1MNcXPqLd7Gvpu+NcHipcSTL1Ct/d/jFoXGz7inJbV0++8Dpxb56ovfPc04doXAAsycGUivRtTllmzpxVS08TvcQ8=","layer_level":3},{"id":"e60a259a-fab3-49ad-b431-ab36230a765c","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayMongo Webhook API","description":"paymongo-webhook","prompt":"Create comprehensive webhook API documentation for PayMongo payment processing. Document the webhook endpoint URL, HTTP methods, and required headers including signature verification using HMAC-SHA256. Detail all event types (payment.created, payment.updated, payment.completed, payment.failed) with complete payload schemas including field descriptions, data types, and validation rules. Specify webhook security requirements including header validation, payload signing verification, and replay attack prevention. Include webhook testing strategies using PayMongo's test mode, debugging techniques with request logging, and monitoring approaches for failed webhooks. Provide implementation examples for webhook handlers, event processing workflows, idempotency handling, and error response formats. Document retry mechanisms, timeout handling, and failure recovery patterns.","parent_id":"cda46bd6-f210-4ff9-826a-1df0b3cd252a","progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts","gmt_create":"2026-07-23T01:22:38.8656088+08:00","gmt_modified":"2026-07-23T01:33:15.1273011+08:00","raw_data":"WikiEncrypted:cX4Cq6ycqUrOaFkgcmNdXymKQWn19e6JkVT/QbTnFEoVBkbUlep38cQOdzBPe9Ef+jAGlJ/5vhMVnjjuBThugTwLLiKBmQwBNJm6rpimNRf1Y/0FJsplVAyHqeBZomK4ahBxU9RI646sKkENZIZ3qgYjnySKoe3wYMpjXN2In7INZKgTNFu3GFJ0alaQMpIvMmTtgy3MuVtk12+IP/XPl5fLk4Js4d+obppohA8V8bnDcvG+Ftlckf0goMgc9ijKkNg4eV30aryjwvAcT9NYzXY8cJNWD4xQlZN7naGMOQVoW8uv5vn5Rzse2sKKC8CiT6o3eui4yAeowaFOVb+BqzH/q/FEpwL/SMeesg4lP4IIBn3I0UiN7tomHd2h+abbG4at7rq6NXvR2cIo7FeZKsEku0vJBbPlCuW4Q6u18N1mLbqG4xdJxt5lEMkv+eq9ZljD8CtGRJR4QSoiIoxtR9YF5F/LtQv7X5bdA5JohVyIn4R340JnkAAHi7LqdzV5Dx7ED/7MyxcMjsDXHRFOg+enujEDWyopaZ3lkHcBY7BMt3V1zSUKh/eLhny4XsuS5WWirzA1nStaWhv8W1oFA4qL8qWWc8YM7Wzp+c9+//3gS6lYdaGS0WokD6jVPt4u/Djqoox4FIgBtTV+OI0zoF7PAw2DbONTmZa75EP6qqmCEDhdZlBtFxChYkcQUKUjPR/Lb04hAD03VqsgaSShfm3KDCIbSKQrvbUX6qwFbdzBBGstf1GfS2a0QTgd50QWjaQ6HXiewpS0QxgWn5lMARI/LCgmCIKUaTcuLoSNGrg6lp9YtBBd7+mFdcAE3F/xKaTj2g5Cs3/sDQK4px/q8yntwTTuk0v8FvR7DG1dAWOd9nVQC8pabSv3aphD0YUQYgfcgQeowhEq1uyS8uwKBLpi1b+77r3j7f8f81urxNW6+0D5aASUaXRrdDKnBhMDqVeFiykjIrWWlSnB4U8V/qippsOyGIOnQtlrFK6r46eslreujlGrb5nuuN48c+9SQ7APoyAR2pCNe6cQAJq5IhELyNrIypZXpJ0bjNDRlL2KQc2JTnqMKocJcErj1L+ZOyvfj3yFcxJ4gNwvUnLPfAvanvdCZleCqb8Lb11HF4ra39t30k8RoP0BEDyERpK5pEvEYeZzkkorie4KCTBwwHCHFpmOoEO+eM6UPGghjfFPSOLdhTo3uWDgsf7bwxVRR3E4ZLlpzq8Z9S+gXl+N+6pPKyOxduFhBfQnJBk3geYHSkNcDQ7hAuToxrrUnNdI6U5HUAZGg5el8OZejfo5IHTrZybLBLKs9xao0DmM+5IrJ9UZhbVhG/bEpTTrnADuJzNask4VvQCl53J16J0qCP/NeeDcJxcBZFajn3n6Z/xuVUKj79L+mqcmCJ5zUrHYIgabEGI9znJWNS6ySbgBL95n9oW460XpZZk4nTxvBixVaayUpnfR77ovAGUxkmPNh0e/sDiVIAG75Rzfz0yOBamoenwG6A/jIMYyUsOXtTgDUL2/Vip1NNzYhZsqQkeUOkMSyO1AYxEV+rYTDkNkkpCTooasCBMcMRJYtfe59FVconrCAymLhpVRcIpyWOUNTv4gay2zInXreErRfjHyxtfLJHsOE1E1WDgAnhRPk7+Bq5KvUbwc9f2kgqysfCX8QC6xETEOFoF9skwBxyOIRw==","layer_level":2},{"id":"36c95a35-68ff-4e50-9375-cde78d578892","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"AI Proxy Service","description":"ai-proxy-function","prompt":"Create detailed API documentation for the AI Proxy Edge Function. Document the proxy service that handles AI model requests, including request routing, response streaming, and error handling. Specify HTTP methods, URL patterns, authentication requirements using Supabase JWT tokens, and request/response schemas. Include prompt management integration, rate limiting strategies, and security considerations for AI API calls. Provide client implementation examples showing how to send resume analysis requests, interview questions, and tone analysis queries. Document error handling patterns, timeout configurations, and performance optimization tips for AI processing.","parent_id":"aad58f1e-81da-47d2-9000-d1e4cd8b660e","progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/_shared/prompts.ts","gmt_create":"2026-07-23T01:22:41.5469033+08:00","gmt_modified":"2026-07-23T01:33:21.2813168+08:00","raw_data":"WikiEncrypted:jLB9r4y2lG8K6C9DNsjHlIs4lyIhyotdJSuP/oFL8fmjZcmIylTxKEBEAt8po0Pr074X8wfIaFyDKqBn0o68YWszNuL2+LcNktD7ZXWXbWZQ3jw+phLx/NfEePbu4wwKzTq73ADDkiCF6sCKbtyDtON1kUvRb7YJIj/4Z/YKQoc5bvykC/1Cs/IX71xNPhY+igsonb3XkEvAM9wMKaScIYmNxYmFQiTgk63i5OJr8W3v8a5YbW8qBbaYeoWhSRfz3g8k3kdn2EpZx7WluGa0oEF1lNVFrwcJcub1fNz92hXnORdpJa5lRS8zcVDGMCNpUSbck/keDWPEFpSrVCmbPQQwc8FMWVju8HYY/kSxXH8lJog+aUZtDrysxeJAqMGYo1rW/CK73vXac1SkZUvD1j1PvvsWdpEmoDvDG41JIImeFmuMPqfhlr/VAl4MyjNOW5Q4CuW+XJyUq4B1STO9ExiRX9mCzzg5YKyg2Y4UNEovHTnW52361LDUFxFuBaHjxRIjUIVz47TnvuLZbcCjU9tjX2WTebM9CgE73jDYQ4AyoHsEeehVDuBHyNnUy1zMN9rjK3Q0BQnURIIXIWCSUaVxKmNSyA69ya1hTLs0YlqxiAPnblbt7LmKxLusmHz3UjCGjLYFmKnCB0D7d2tfFuTcG9ImW+TIMSqSO1AD0kwdDsJMc+sJAl8PvfgC/bCiXK45l2kFkBB+USzpegcyg8qM5kUD0XSp6JKFrei0Pjvf5BxBqX/03O1KONO/jsUT0zksVnmPVavl/K2ndJ6nbQMygBAxxMZYaaL6Ih4E043ivnC8Q+CqLUb2b9m+jcHoLcl4SMd8dJQ6MTB6YE1bhZkAF+eYUpJwckfLzqEdZqJZfKZsZiiqYY1mOqnBBXJHLfRnD9a5gRIo+5NXcXel5/uuJtqvYtaxvae/dY124ky4khhnEXAcro9muB7+q1w9Cut+7N6SKP9NR+xddUukrZiyudCQrB9t9QwFNGdfzghOSTFZm4sv5SndtHTHvjv2iuTCotzF+P9rzOim9p7bO5ZQU3q8sjBUXIjyyjOV99mw6NAmo01urN0vWkt9Lqjvq+uUsuVKkOeWZEbUXpM8STzkNUT713jvylvcJJ7grbfay+jxEEct7qouTGlCjv9S5Ypyo1P7UB1lSHk7BoLdg7oCwCbrUNycGhOuNDpaA3Oxr8QPxgudGyaB4x2/ONVe7i8l+XH7b6ikAG0hhKmHEc/cldib10xCjoJ1XuwYgPNsYJDM4XYiC1zBvCZGmSxJs7wu//iVKfFHuz8P//fa2yLHVl5FyUAHQTLz3D32+dmWnugQ42Gb45cKZjq+RnIxFsRTY8zDlMbtB8wxo9yc8feXPcOc/yc92qlTAfxmADhDrqi/JTIBYgOjySAlyzZayPoiyqSj76cwPMwGDryETw==","layer_level":2},{"id":"59e209b6-68c1-49be-abec-626bfe7cdc1d","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Layout Components","description":"layout-components","prompt":"Create detailed documentation for the Layout component system. Document the main Layout component architecture, navigation structure, responsive design patterns, and layout composition strategies. Explain how the Layout component manages page structure, header/footer elements, and content areas. Include props interfaces, styling approaches, and integration with routing. Provide examples of extending layouts and creating custom page wrappers.","parent_id":"80cd19aa-ad84-4b1b-b83a-8a34a7c03774","progress_status":"completed","dependent_files":"src/components/Layout.jsx","gmt_create":"2026-07-23T01:22:42.7380599+08:00","gmt_modified":"2026-07-23T01:39:58.0102192+08:00","raw_data":"WikiEncrypted:x3LcpLCzT0KOPxd1xeYY3c7iq48qz+WPAPm3x7MWgVmMN2ZlOrEZdaRXZxaYKQQDsUQUaZVmttBkOliYwU4AUPu7K+eajHQg+SGNL4CrXvXphLtgA8VqEibBLdr4h7PtbI0iEkl3U/JmpCJGIfN/6iXsSvqc6r2pz083CpjXhoqaGjfXoOi39NrJg1BDMQ3De1EXjM4XbyNKUGRFALy3cUSHCwZ47v5Y8dqeNbLGHUnit8eR3pnq7x/3Iq3MU0wSxdyz1SdISQR2dOhXy6DtwQR/57NVSQuj7xWk7RIeaYrytsSq6K0qpn4ZJJf2bVcW77itVcqTp84GZOKk7xgyTmQqQolV3JCycIPx5LwHlTUaQ8PakHr9myWP/EuygAld32cRRYEj398cgE63T/TVQN7TrD4HFg3NdQppny9X9qqV9VHa5uXsYPaFdbhzfeGHLEAdY1PUo+16mEK+szMyusbnCji+6Rd+Z/TP5k4Ix4vW74hQqrvOBQ2pjn2NMFfPUBHI4dw2HOIy7RHzEOajfLA+QGaj95XbA74G2X6wBmoObGvnd87GhKMYoeJ0+K1XS7FGHmisHXkS3xisS6XZni6/HBZT3/6wrlzcNcwwUKU79oPhUHGH3mQMTLx9ckAV6Lb7SCCRAU/XXDhA+XCfqPpwCJmRXBNEbcmib7NMdzc5HfgseaM72ZbW31rSvDNTKEeVvMKcRdp2aph3G3ki/vENccHPjvXL5JxloW76/vsxl/jxlOqS7d2/y6cmqA7PyBPT/qXFjfdADSs3ucCdcmZCUqsyotr5tNNja8nJlV5c8uz8ty3Me3/R8IZcQYgyLg/jigkyTsjhjKyiqtBLMGdDK5n+rWP45VNmWqCiMuwUNavHrOBKXZ8p++YGzJk5bx4Uc9bCmJTbJtPpKJ1WBOLU6+M2tZOkfgO2xopej2uspgYpeUOj9Avef6nZw0NsWDNBtVTxXHoIvX+/AEyd3XAuUBRqOITSRV6kJrHPYbwTbq2o6z/tFdGznt5fT7ttZDxJnR1kxjcMN2Ra579FftXicAkaUZBmpAI62afa6CY=","layer_level":3},{"id":"4485b7cc-5d93-4fb8-994e-c8c5ad2f3f95","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"AI Proxy Function","description":"ai-proxy-function","prompt":"Create detailed documentation for the AI proxy serverless function. Document its role as a secure intermediary between the frontend and AI services, request routing mechanisms, and response handling patterns. Explain authentication validation, rate limiting implementation, and error propagation strategies. Include code examples showing how to invoke the AI proxy, handle different AI service responses, and manage API key security. Document supported AI endpoints, request/response schemas, and timeout configurations.","parent_id":"ae6aa76c-b442-42b8-8ca1-b2688bab85b8","progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts","gmt_create":"2026-07-23T01:22:46.6344583+08:00","gmt_modified":"2026-07-23T01:40:45.4201087+08:00","raw_data":"WikiEncrypted:jLB9r4y2lG8K6C9DNsjHlIs4lyIhyotdJSuP/oFL8fkip32jbL/JsgFm2I7LOsSQUkFMxq+rmxcVem8v7uEq9G4hSzUaUB8JYFab8OiTMxJU8P8GTsBeRNOekkmNkXVg5l30zsY8yk13pJuMt5fXYChNltnpWqSl6L/NIxcc0xtt3fceE2chcJJ0rio1Zzwa9SWsDn4S9r3XhN6++jIXFQp7jJBBjylZHTIkujGBdcAoY6WdsoD1dRvdnd0S/nwxKXfhugr7mQFezDV4vbnuG2Cv0yVUrBXCATpqXcKtvVphsX1Kx0ZPsZeR5ytheTsdvGRQN3XKaiAGvVhzfJaunz8Tiu/KRBmQ0+9le5OMIzoS7IaV7vn2t9X5g9YTqgRVsjAREI8BPaeVsCer4wxr8rFIGGBSd0gGOfzWyE+0kyZBmqxTsHW1i2eCyrF2+nzd/fw0fYBWrSDRAtW+Ka2jedkCfy8JPEwO3o+JJHPTdc1jamO7Ten+jSb57C3uOtxj+jSBTW8qRMcel3cMTSNyn9wM7UZL9S3Q+8FHL+rV1pQ2BBIl1MyXiOk6l43I8lNbDC0VODXrBxl5oe61VRzPcsIAms9fck6Dzjllw0KMpEQV2w/JxKGDk7s9hdtwZ0n+1Njiaf0J1PIxReKRxDdpTTQ87u4G48aAELXAN89GARA/NpQzfRT8XDTisvvS5hd+Dk1OgML44UDaOx+5L89qT37Wb5FgmOGR5lt8Hc8vIPPa3g4d46heKDBX6QlMmlhNELjrH/0pG79HZy2kFawqE4k5Inas4DJpYvE55SA1XNFFlNBo5GBnCsAU18ASHw69fXrJCHpjzJjj238OBve212n58x1Lw63nGm48B2vLw7PNQ/e6TSy/9WvfearSW5eWJLiR4XLyk7kDKuhUdzrKSLwI2lVHcYb3uFk5SisoVEGB2jGAjQhP+1mvZBLyYQenlFuSOeqsfofMZh3DPMLsYRPkuxYgjllqC9HOfr3wZA8cUWCO7Y9gbuG8tCwlltalZyYzmuQQNMoqSIh5L9Xr4X9DGzp/DR9VJCjpLfehzfcFts8g6/Yo+VJM8SAcQiODwQcuLy31u0casQqSMWlxmpfPDrjLR1SxwbojVjrLuO60SkmZRi8W7OEDP1VTfCVf5qPojP8RCe98SRSmOOpFSJJBwLnOdC8pZBtCxbrx5h4=","layer_level":3},{"id":"abd058c6-adc8-4d6f-a32a-b642bf97166b","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Checkout Creation Functions","description":"checkout-functions","prompt":"Create detailed API documentation for the checkout creation function. Document the HTTP endpoint, request parameters including user authentication, pricing tier selection, and currency configuration. Specify response schema with checkout session details, payment method options, and redirect URLs. Include implementation examples showing how to initiate checkout flows for different subscription plans. Document error handling for invalid requests, insufficient permissions, and service unavailability. Provide security considerations including input validation, rate limiting, and fraud prevention measures.","parent_id":"8c623eb0-3465-412a-9717-f8413bae5ca2","progress_status":"completed","dependent_files":"supabase/functions/create-checkout/index.ts","gmt_create":"2026-07-23T01:22:50.2751984+08:00","gmt_modified":"2026-07-23T01:40:46.4613685+08:00","raw_data":"WikiEncrypted:/3r/IgJF/D+DnPujiCpodlcVnt7P8yexE1SU6erPEyWFXeqiBeVeZeHM5+pGS5fK6h/swJ5xe4vJGoSlQOdtirLeXhTKysHtDwJhrfJPdZU6w9qpGhGdpAyijVteO6yUN5lzzKeK/KqVDzKXsbjgFdX9a2UEGCi0ZSuwMgj+bC+RtMGJ2RuIdxhB9QBk2yDJd1ChFA2UMnYxqYW3JhhcgyxJvHsZth2OdtsrI2VPrWDz6iHY3mgQX6EXcqBT9AaNU1kfVFAXNfcuQBNWwgItRW53tVuOhQbwUHf+ezenxyeklqwnOBZ2pc9u8cWH1HfujdzxDB30JLErdg/vOKJvlXhuizkWfYLRJDOgqzGSSabsDG6NRhZdfGVV3bayk0Q+r+udHqHAANJpF+h8wRUPDcShEcknYZKpnVfBpDRfUrWrU67BCCpcjy4tbkoKKtCmR0pLNOZCP9fo7/rANXK2NU+KiELraQhxMiq+YD72LmbnUAWlwPJ4ZrmTcg9DPE0KrdSDGEom/Uj5ynMu++/TuajkmzABktGCRTPfeTDVm1nupU2/04px/DHylqa/Ka5J9mRM274STJlMI3V4w/c3vWyfYICNidbUTzUanBYZG/TCAVQ6OwFNIZCTKlsDzVI6kWM5gah2H0U5ZpNsX8iANtoS8ZLZws8mVlGo9cVs6VrFEkbK5SIfUINe/AFlhGLPC+t21HetSb7tc11pFzBsQi11QJg0tO9ARBaF0o8n4UjQf1l32da71FGXp4hFVc7DJv74dpcd+AWtSOt94Xp3JUUGn0iT0jfm2mMq3gJ29b6k7lHylq7jIDhghDIeDhPpWGNOuPqEBh6aPpheaPxOLmdYYT81KrddFlY+i9mOcvslsiKuJQdyUjTd+SwryfdKjp00WFgaRdyDmvTc3A0tStZRCbXHwvX/9hSVTQmcEDnXttB1OdDWikHzOuPXzHrqd77V3C0ORMvurXIHs8RaEqY5CtVZzZBt7DmlFac0rJVfM7sK2889Ru5/l62FnsxLvmdFNI6PiE9eNx987+z2bLDuJ8wr0gVxrT/PbAUq3+OTYqmWy525/5bohHJFmD8wdYUe1Ko2pITYQXnJnF1b3iTLCqNNzC5x/JfvAYww09ijeoqNx3FCgtw694w7YoHMyVZOUbG0dYB3UWV4jJjtnyynVZi5zHY9Fqhumj2Obv6kv7ui6wTQVQzOzHl2XmV9D/WNw1gw7ssvXCVnD6RpKWz2yBFPMaBXp/O/zj6RB0EHDNudkwUmBQlUo891RxTG0m8lrIBqBS72em9wUxAzPw==","layer_level":3},{"id":"f4b74e1a-5e05-4fc2-a6cf-0a60fc33e506","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayMongo Webhook Handler","description":"paymongo-webhook","prompt":"Create detailed documentation for the PayMongo webhook handler implementation. Document webhook signature verification, event type processing (payment successful, failed, refunded), and subscription status updates. Include examples of webhook payload structures, database synchronization patterns, and error handling strategies. Address security considerations including request validation, idempotency handling, and retry mechanisms for failed webhook processing.","parent_id":"672fcca8-aa26-4601-b5cb-90009d3ba4a5","progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts","gmt_create":"2026-07-23T01:22:57.4374371+08:00","gmt_modified":"2026-07-23T01:43:21.4025657+08:00","raw_data":"WikiEncrypted:cX4Cq6ycqUrOaFkgcmNdXymKQWn19e6JkVT/QbTnFEoVBkbUlep38cQOdzBPe9EffihEv9KWBZf/Wg/2AvBGR6vwEsQZTh3fRx04hsd7SMUqIIaG2vH8P/RjrKA1cVxau5QzYD2aeOSc/m0u1rgJkGsCBrlhg6z7JxwOP2bcpZzgb7EGBa8amtpkprYisUc6baaDBZSimLxwiyQyMshjcZcQlm5af6o8TfRipygOLAsuViFpNuTKQEos26aI2Zzu9cKGI4okLaRLqXl8ckc5VRQAQfHcG/0brnN2YgXsdFIjR4tfrWFxv8VsCpwWmqFEeqpsLRdsE34cmve+980ckcIXujni8y/I9dzr7ZrnXiHnS4yzIIiIRkGHZ1sL7YNHs150dAppDcRyM/ewPvQwi+UcJGq5aQRi7U4doZtzJVrXJ/noiJ/9Yg13zaoyYWkDy7jHrRjq3cpL1Mvq0zBJSUdsmaKBknZnAWV5vOd+coEeE5irwtkd3zfLK4MfGqT91hJcKo5PsKs1porIMM9h2UYDNNJk1UJDYeK5RR04OXjSsTcJnLY7gkJZ91pJZ3EaWMWuPZ3WvrEqyD1sRqHPrzossA1zINguWSiRV9lECz7j5jRkYPwxsrUumuZnC/jGlQsjfbJFx7JBpbd77uqVY6gZZpuC8bW1csrkZYTPRDepUL+UUJ23+yGB7gie/+GdAPT2L8xU+fGrFl6Naa1SiU+b0FPOLBn88abSO9QXsXzWWFfRsP6yydZxJ3uLZbWMp/+AX0jl17G8rRAKWMVHSaQGmA/jXkjzuumaXWXf58G1r2QuC9uaTbVRx7f6RFryZoRXz51cDFWjK6OdBLM5arFiFQlpJN7s2dtmNNnjOIGIhboefQ8YXYXfoUyLiNwJwwjZ964Fi1o60S8U6k2MfP63Qk0WoEFRNL+69taz+I0A51lHkg4pTuy9tEhX51xyFkNZwlwr+OeWocSoYDMUCnGG348WSuaFFaufAckz26UZu1NpIZzMmgjwDS4nbTQzO0Tnxbqwz2CPDePx2sG/FdzfC86xQTRXp4JBSRiCRpYkyeLrtopUmaZj2EaXYqF675bLErq2LcZ/3E35b8dCvl6wSKGu4c8+L1DIHZ9fqo/pC++M3HOTRMn31YHbdw1eDRpQoJy29oHhis94Wbwn25l/v7d5+qJXVaiB3PAnOCE=","layer_level":4},{"id":"b875171e-89a3-4da0-8593-431fa7182cfd","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Getting Started","description":"getting-started","prompt":"Create comprehensive getting started documentation for ApplyGuard PH. Include detailed prerequisites (Node.js version, npm/yarn requirements), step-by-step installation instructions, environment setup configuration, and first-time development workflow. Document how to run the development server, build the application, and deploy locally. Provide initial configuration steps for Supabase integration, API keys setup, and essential environment variables. Include troubleshooting for common setup issues and verification steps to ensure proper installation. Make this guide beginner-friendly with clear commands and expected outputs.","order":1,"progress_status":"completed","dependent_files":"package.json,vite.config.js,capacitor.config.ts,.gitignore","gmt_create":"2026-07-23T01:21:36.3286914+08:00","gmt_modified":"2026-07-23T01:23:30.5465831+08:00","raw_data":"WikiEncrypted:qfgbutC7oyxR6nMxrwk1ODnNMBEQ3/sG78fQT1yXWjspqw7wFsgcSykO0UmGZY8QTKN7XNoRj5gLcQItLpCOKZ9ZbHle9s56+Of6lOxs4mxu84weypCHlm9ce1lbMwWoO6J7yE6/UgrJt1JeE12tdQ5l4b4pNQZtrf0bTQ8qKvjL0gZMHShD1+l/dJd3szxoixge9FyGsmRMe2fRVRfL2No3UIPgtakxsTmGfuk+JFNUHun2r/JY7LOS6voFm4Url/vES8UPUTQ3zeuUEN6CfnV5YnjXHKPW0+XGRvluLVnq8Kgsinckt85VRyS0vLEY9MMMs5t2p2KVWZWcNslliLkYi7lOlJhjHj8ztY0D8yQO5uv6Y5my0QkyUesU5EWHFKpvDzCtGCU7afvYSiuXWp4RZptOGd7hyl1Rfxxd4elpQN/yYSJ8Jp3RODbrJnom36x5XnoZvfZE4MtuQyvW02Dd9LUWst8/W27S01EqezZayL0QHhzq1PaJWg2Tu/tFRZu3GQFQ45t4XdJgnP542/ooWKC+u4JHitqY+BRCTgrIKuHTADkL4x4UN6GLm+rAqVVFBSo1OSPE3ZdmjtgbnPUAqYNhS4K4kMOqM/4+w4dCCuRpeCxDQMVeKa8Uf9D4pKYxsuvw7tggE5gIYMOAgS4tnNJd5IBC6kSZ8sLz7Xj7YmzILw1kaNUSVBLeDZzB5laR1aQn4ZN2Ok4n8jnOQc5SGXvFLI+JUdNVZOqnRNI8g0xT6ASO5Mo0gAW9u2rfioaRqCvYSzNTG0SeEblEDTFiOKJXJUqWvbDM2Zui9GkvPHoBop0NzMP9aEVmXR2u/tkIUV6n42eOhbMHvSgcohE+lC0UDnumtW6dYGMh3YUVQZfv1+UAkHd2DT4tHq0DO81P3TXhwwbrVgKBObN6AH5zsHvi+GTeHlZMO7QbLSped3WZQNYDHtp9zU23pVU3a/PcTluyybT/chseotx22p8gvTNWCCiTyX8w+aBf48wRyYNbqOOTuj3Dy6q2x9HTFaQgSK/78GmDkOz5zggmKHkQ5djh4WipFZs5PgH6Bctnt8uXgtw2yYSTqpE4BXWzdVxTxw+G4ZaDT6lcBsxT1FsiZPcWKIlFvdgtJFvWZh+6GKjmaF7U4KVoZDSKFU+4XJCwJ7crsT/z1dMywENy7VQRkDZyyAawueoDaaLs/Yon+Avy6YoUGIrvWte0etaj4wwb40DniETi0h/KjCgGb/Y9+JmnqaJWcPug0DP7U9vuVvK5/Tmpgx8T4BaJGi6CUBzbDjb5rrK69pfseNHl3zcnU14RTiKeIifsR3Pmzckz1CJFSYh+dCHwEKdTFhFr2B1nfbN0gIdqxyFWyTiXWgwGqEQpjsnGq2BKyOF7U/c="},{"id":"531c9699-6862-444f-8f72-71e9b8983826","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"AI Interview Preparation","description":"ai-interview-preparation","prompt":"Develop detailed documentation for the AI-powered interview preparation system. Cover the mock interview interface, question generation algorithms, response evaluation, and tone analysis capabilities. Document how the AI assistant provides personalized coaching, generates relevant interview questions based on job descriptions, and evaluates candidate responses. Explain the integration with resume analysis, industry-specific question banks, and performance tracking. Include examples of interview sessions, customization options, and tips for maximizing the effectiveness of AI coaching.","parent_id":"564369b0-e95c-4c08-81ae-df1e1ba0bbb0","order":1,"progress_status":"completed","dependent_files":"src/components/MockInterviewPage.jsx,src/components/AiAssistant.jsx,src/lib/ai.js,src/lib/tone.js","gmt_create":"2026-07-23T01:21:42.267991+08:00","gmt_modified":"2026-07-23T01:24:49.2469016+08:00","raw_data":"WikiEncrypted:cziBIEQqiXGL3msY0WwrlpLvTiYUbiiP/uhzxUTr5eTamO3aEpO2xcne/rjxVmgvn1/6EkHTEOO7ONyF7O7btq1EesszdV0c48gv8KLJBWPp64hfpSSH1/BVEEhWigDl7x7skOYCMJOXYfGSypJQRZUBz6wy3hxaykem2aZxvLdyJIAKSLOsobYuOTQCzrL3ctxaGWAnnGsD92oP2pNz6hby4klaR2N3Xdp0vBkwnVen66wjnWud26tpMY9gjj6mQQPx5fWieHSNLaM0OOKETKYGblJhz1st+i52c2jDDhN47aZdMcrfrllhzXK7BfCXxbQSDBxFhh+LMqk+BIhgsIEZwgPs2p8uqhM6TQPmOx70PqUPOJvTEa9vzvhe1RVFbQzEP82+iNPhNfOsZBpq8lD3tQE5NLiYgJ8Ig2nqr+UNQC9SOaD0H74Dtm8c+VvJI4p4dejAZu2dcw8y1ePSZ+tzVyV2b6xrBtNi2Xee8CleflCx2Qv9ll8yq5tNdWICvcQ6dJ3G72+KcOzj18+x3T+J0TuoCo82WIb0x01HCzixwLuGXDYJ8DGBpnkgJuQywL2B4kv5CPn4OT4NNN5e700vQb/WN3RSpDnBNQ9Yb2JI9Lsw/w1RAq0sXGt/3nWsdTdC5pW5YaZ0eLOfamKciEJp9myJKyJKtktco8V4JMPFnHS/6It0qlbAF/EgQWLsGF+uyj+uMuRAZvQcG96K87SKfJZj4FopXZ/DrCGjaMfrzAUYfJWyHDhyBrpkeWEdOmHo6KLbdwnkbp9HWVbnBb93hYCkYohsVcfEhpWNQ+P/2elaLvnBwPeJbCrddgr9548Wrx+a2CGSFrM3M6PLAlq3kQ2fQpHbQ+ABgu1nVk/s5sg/Ujqq6rvB2x2bcwFTiJFdpladCyhI5+U4ZIXgHCr8tUOF+gVgLAuk5HvuP6Mj3azMshsbjkGrp2iI94o8axtWhmhcYUREGVOzG6vgQMju+JTJt3MWV9o5odDyF3/bOdXbibi4QZv7+r8hQcoqvRDwaoDVQrGYgnl1amk41C1m0NXFKBhS4eu5yAEcDkfNhfajeOvpRSx/cr8HvXBUrDpaTcRTo2nPgHP1LG4ysb7CDjX26Md4002O28hn02oReCVGANQeV4XpVJGQRU74g8qbdED5stZoTU72wp/mv9S1qL06sd8UR5GPBWC5Giiy9jJ0dTmLAbQpP8uZWNARA+ah43XAo6u4/2MMCS4lCWqa4HqmesiV6p+mgEoPY3++N6agW/7W1O3R1liAgdaccRflnNugtJJx2d4JnVNbY3qbCMLfBx/0XgT2JS9n0PXdmG8H0bCxFH5F0yVT2l6gvnEkiLLwMduNeqhgZ7pAPwDMdGBNQlD/rGSlTtUL5cIaliXFcfcscT0zfe3LO1Jf/1/F1x3wzaF/r47iklsH+mfijYzUQlJyJ82WATjID3g=","layer_level":1},{"id":"15e41105-5f69-496c-a0c6-d162881bc0aa","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"State Management","description":"state-management","prompt":"Create detailed documentation for the state management architecture in ApplyGuard PH. Document the custom context-based state management approach using store.jsx, explaining how global state is structured and accessed throughout the application. Detail the useCountUp hook implementation and pattern for reusable state logic. Explain local storage persistence strategies, data synchronization between local and cloud storage, and offline-first architecture patterns. Include state update patterns, performance considerations, and debugging techniques for complex state scenarios.","parent_id":"531def32-f496-4527-aa66-895ddc7ac7bc","order":1,"progress_status":"completed","dependent_files":"src/store.jsx,src/hooks/useCountUp.js,src/lib/storage.js,src/lib/sync.js","gmt_create":"2026-07-23T01:21:46.2883944+08:00","gmt_modified":"2026-07-23T01:24:54.2315205+08:00","raw_data":"WikiEncrypted:29DQGcj0Xkj5ar8OataJBBxhchc25ft/oSjDSUQ9oFMqkEmznfs18jsO8Qk/7qxOyzmw6WXtqMjp5xg7mxI4VZ63ztCMk6ghG4AU5ONrFFpnUdN6EF0tfCJmUbqvjIjYtdjKj6Yh05vZWiQ6Lc9OsiUWNl1WDd5h1bMaHZIPcdZq/JpnVSaHNimxCX9hZJe29qqCmikBm/Oam3XqVarEUb6FhVIoTogh8BCTWvqIuLbSLI88JifNH4XHwQFNLXHPSxvo8EfCOyRLi3i+T5L5crT6UQGE89j6t7CwymRpBzbnbuH/ekK2sX4iJoeXxV+I9r4Xr8BZa3vNObIRcT1V84TRADaK5mxvIvXVcCrmkDQPKdsk8b0aHW7kvRPvQBotS9c+ix02+FQZS+evA5Y9JakPsr4ptrA9QxKW4YgRAVllYQnZNUssoaHpyMT3V8l0L09INUFmJjeAV2HmgcW7iNPO5A7R7s58oz1C4Uuz6M5Qe76I/0vjMaz/aEy8+vddBU6n/p8LHwQnNTpKr0pZ4RvvYdoCB9YvxCK/oh8CevkLWsGHMT1wyTYwcod8Wgir5i6VNSfBrWwVqnuolcP1VeonsbdpjR+Kkl6p0wcSoj6HUMDJqKoDi4DpgCq/n9soiKgS/N3S3saMsJkb4ezD0W22B7dENGpU6cSL48ACLMXP5nWnEQU5unlAQSdGqc3C3HD3vdW0hOc94j17+OQp+EZZuRtsjmuOqguKhfep/0bI5pnDPHcTBrg5hbiiLLPKDbFEzmcfItDWcdRGf9qGQxbFsYg+NQ1C2oo6x3/224+MhCtjAOQ7Pm8RkRTiz/rjtErILtAyNFzkd2s6OUpKwj6Hg5l3xTFOI6m0EkXu/ywHCrUZbMOU35KvwSvQGqMVpNqkMapiCtpSV3njdApt88wnyYIjv8tLxJ1WjNYwZpthW85bE9agFOrDRdMpYsSPixwqIqjlaEd7sWFMQK2FiDxASgzmAbOhhj+TB3I0HYaiJcijVmxuPpTO/SPaOxCFCn/G4eyMK9jHg5Rd+17q2RE0DcpKr5MSXJ+QKJjVRGG1PRYUncozPpg1oMOxZiAkXJns/7FzqPngmvnAeGOtk/MJFrRfG9IF/DLhEna5AOPs5w/HpkIC3fkGPu/IyBtCa+Q1PfwplI2e2oRdn2sCozPatn+rmDQtATDNiE792aKxBrLSdCH4tXj9z++mbv3AZadYeDIGuUXjEq24dc/rL0lqqnMOoHK1hwjopKZm2Tx+TqfJsH2/8Be6cnM4A2uLQBeNU+ShVBdKf/TKmFJIpqnkpqnOAFFakD3OM1L8uOk=","layer_level":1},{"id":"bea14602-7013-4ae9-a2ec-8f0c2eb62a02","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Frontend Architecture","description":"frontend-architecture","prompt":"Create architectural documentation for the frontend architecture. Describe the React component hierarchy, custom hooks library, and state management patterns. Document the modular organization of business logic in the lib directory, component composition patterns, and styling approach. Explain the build configuration with Vite, asset optimization, and development workflow. Include component interaction diagrams, data binding patterns, and performance optimization strategies. Address responsive design implementation and cross-browser compatibility considerations.","parent_id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","order":1,"progress_status":"completed","dependent_files":"src/components/Layout.jsx,src/hooks/useCountUp.js,src/lib/storage.js,vite.config.js","gmt_create":"2026-07-23T01:21:46.7715639+08:00","gmt_modified":"2026-07-23T01:25:17.2335488+08:00","raw_data":"WikiEncrypted:rJ/rIw0gVau8jPGqKFBAsMR2XDSFypkKHZQ6YBOgiECOtpjxeTIDctgQDypcHXj7kWhM29lH4ncuB1WibpCOXkrAesZfcY5g3zI8bvApqqavHZR0FFdrhDRndMhyO9yIQxVjY+a/ONiirQKAYQcJko6Kj69XmjVPoT612DtA4Pg/ijSYT4gBPa6wtoBsKJAe0vgazCDmW1wGzek/d9GVIwDGOlHSaJA5nBIpwk+UyrdwxxfJ6hUnNoVSICthHdzkx2ezGHM2S/HXE0qyPcH5h2fCKUZdD3W33nIl9YSbvMaS+/OiRl9Nd5FHclf9f5ZHtLJkrdlgaQsjOpdBZQGW7aTb+b7oBRGksADOauoZhOsZJZi56Tj+L9TUFtfA31umg3in0roKYCrF30M0m/pS1c9+JFf84zkAyIRskthg9igdwVO07PoQ/tKyYqoMest8Xo5N7zHsPo+8fU4FVqxZ9/7BJBkANnQnqyrb1Bw3Gf5wvy07k3q1gTdQPLwECbhgG+rKq7fajpc+TmvIM/kIbrOs4E+4IddUkzqfPx+E3uJz5r1L9z+71qclpLd7atcWXltFO2qOGGq1r6W1TrmnZ7WyEeZfUhL5VmJRQ+iG8j4TR5q28BoalAokzNNYEbVc40HWS5mKFpSdw4SISk+c6zOyP38aibJl3jKEC6JIBTamQ3enwxwD3jdBPY+l0VOH3NCXfs4NkGShkJqqw+0OfQToXguFX9vndf1vSL4qiZT6puwl0/LLx2FD+BOUq1h1QcnZslLLy0J5Jz/W9nCT4AmArddLUheg0/paQNl30Nf8/zPsj0t4e+w315bhKzxkiHOE11s5rfWCWnLde1uba11j8sWNBr5W6OjW8ts9U7nToW1UfKpBvFp5ZvD1pFT1ML/Dx42LbqVO460Fm6rYkevlXPzWyBKPlJjskEjIHGiSolSK+nnq0aYu2Q/t9PCrewEtPlYJ15D7YEr34lWaQWeH402CDXtbyJQPMMUSH8ky8OE0J8W+F8WZWAaQLVOF7qSBU/JvqzZUzZC1F3N15OdzT5q3n7lFjgRkgWUjKMRKN5oIWf4hjNZ7sP/r09iqeeeg/Utb3sfUZQknbwNjTVB7RuOs6eb4azNYau9owa/U9xi2PDpInk2XbVXDPBXcEERagjX6hqg5UQJ9xX6IvFlg0IcTyfrHpM/VBy31INr0MeMB0s5QJifJid9p5520iMd//nQ+o57L9LCxuoi4djqCn9aLg9GSXQcijO6VEslmnVoaallQo1KXbjItSIj3/pc4xxtlcE8iHfC7VX82icjcYR1cGQBCmWWYhMRaWtg=","layer_level":1},{"id":"807ef1ee-e7d0-4485-9b75-741a4a80cfab","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Scoring \u0026 Evaluation System","description":"scoring-algorithms","prompt":"Develop detailed documentation for the scoring and evaluation system in ApplyGuard PH. Document the mathematical algorithms used to calculate application scores, weighting systems for different criteria, and red flag detection mechanisms. Explain how job applications are evaluated against various metrics such as experience match, skill alignment, and company fit. Include the red flag detection algorithms that identify potential issues in job postings, salary transparency, company culture indicators, and employment terms. Document scoring formulas, threshold values, and customization options for different evaluation scenarios.","parent_id":"1968d404-384a-4a0b-82f7-a66bf82b925d","order":1,"progress_status":"completed","dependent_files":"src/lib/scoring.js,src/lib/redflags.js","gmt_create":"2026-07-23T01:21:47.8595367+08:00","gmt_modified":"2026-07-23T01:25:52.1422919+08:00","raw_data":"WikiEncrypted:XB3PgRmgb5x8Psg1PAXkgQj3YytcipQZBqLncX1SOzVrgNVGlTXfd1z5Fe1J97eFzZ7KNgF3xcI8WlQ2lpJDutZZPd3k7KBoV1zo9ayvPabI51dHbWoPI548o4jB9GJqr79h/A88zJhz3Ij9zf13P65WYWS4iz0aSwjuRuPY4S8/2osInKRu3ZiyPT5DdBPotCfaYoe9M2HJiT1yHqKe4qbkZdAtSsdA9qafVvSlY18Oj2ee2yQoXCyMGz5a2Sq1zw/hRUIuCQmq3Dym09j2APRvAMdP1m/01p4asVxs4/+nK30hLlwaglDoniEX1TJwbcPfWMlHcs1Bf4YNi6xVcqyybiqwfTzgpiWCH+N6p5lIvw67qYkvRHuOC01mxwq+8MTCCGpMkRa19ZO77zrjW2oJyIEpeQdlKaEI5YPG/DMI8wQKDOny7a68AR0YOEb1SaBCi/sLuiJbhtvzbEcf6lXhJ6alWU+eTDnrnORQC+r/BdESTZhzEoXBvw/pkynCMguCc6gl93I6f1dnOOYKXHfhw1EWBR6MZbdnUbMQqErDQHXwP9zDNd3YcKQyfBB37TR8yBrZdAxkL5PLduzmxb7fgt/ZuC5FoxQhx71ibwhVcKiowneBJ230OXzvv5lFqGDW+CX4GHysTY6khvY8MtHAL7g0REc1tQya01LVTSqjbwk4xnKjyQduBgQiBQyPLZiDyOLqhjmCE5OZE+PFeF2FzI8CLSdkFNKFxqmjft8aCptoMMmx2cRk8Fg7GQSL0zFpcMEYwmAawb/3B8dG4n30c/3PCFgGL4aVt9GB6VQEgG1ucbhseHyNyc02lQJmIFbu9aeO+2iJCkL2cu+p9q3j/4WR4dc7XK/MM/CsM6+ynXmMt3VARJungjQbJz1VCgUsc2zDQF26/uSdXnC3ilZ2IElHYXtZjNVY3FL1zztMCTBL6rz0VtFOFGl1h6QutUblLBlszOYNpG3u7r9QLJGZ7K2LG+rHU49YsWMbFUq4G5siq6VnOw4q4bdvUfVAPkIMoDqOjm2j0bgPKwwU/2nC6D3oUAXTdNEWAvegHMsvlAzfKt3NFWEc8UAHsQ2xPRBA56y1UsFagNJzUA5wmea0kXGpMHCmx2GbPN80zlbIe1/Q7Wi4oP+keV5C357EE0yoowZphzOhukL20UUlFeROJ8xc7zn3e6teGkocp4YKTgoSQQoWHtCafcGsV7lkfWWwjMKSlUIPQ9ClxvQ3RexFWbqjNfi7rIsX0hNvd0RwiLhK+PB1oqi4djzyvLWp5WLa85xH9tqXJL7EBxPF9lLtaBDW+k0H7/s8WCPG3oVmsw6NnlS9Jtpcs191iyi7nc4xYia/FJH5ZOwbPYcysg==","layer_level":1},{"id":"8f93da33-291b-4b8e-a6c6-7ec71ff6e718","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Cloud Synchronization","description":"cloud-sync","prompt":"Develop comprehensive documentation for cloud synchronization features in ApplyGuard PH. Document the real-time sync architecture using Supabase subscriptions, conflict resolution strategies, and data consistency guarantees. Explain the sync trigger mechanisms, batch operations, and incremental updates. Detail the offline-first approach, queue management for failed operations, and automatic retry logic. Document data transformation pipelines between local and cloud formats, field mappings, and validation rules. Include troubleshooting guides for sync issues, debugging techniques, and performance optimization strategies for large datasets.","parent_id":"4c08a624-9311-45cb-a77c-0010b16eb5df","order":1,"progress_status":"completed","dependent_files":"src/lib/sync.js,src/lib/cloud.js","gmt_create":"2026-07-23T01:21:51.7728084+08:00","gmt_modified":"2026-07-23T01:25:24.9252581+08:00","raw_data":"WikiEncrypted:42GucIVlAI9L6q+fifwcxfcoEkALXr0wT6WO4w2V1ESqOUSwS5g8GKKWM6MD+a0X8XFJ4sCQ5r2VKyFifkWU8H/mf1yB1jmJmurQx8BqllgfBD8Y8LNHYEr2iBZzvCk24kfdEcfGTRrrbeKj/GOcu4Hiv9i794zsgffoz0hDl2EIo3zF1vQvPMZ2AlUYVf6uD7OBxo+JDieTcz0WnsZmdH2c4o1n7MrDsVIlvspnXqbwjs9U2uw9bDbbtnKPrXvy17l1vgt+D+kds1ZhMFpqHSlVt4zu/t47TpLhAOkTjRRyDe3VuU0tnwQpzG+jIEMNUdJn7OrhraNZzCsFWznaYF3IGK+x3pr2pOcnK2bYEJD4uGI+LaW0Un+OjhaZfPPGAQ8FQGb4QuGjxGs5JSw80ug7NpI4Jssfa0hLX/pVPl+PoXzd+H39XWu49swMY9guUzp+uJ4MT8GKsy1nidXRoVaK3gKUOyF1OzKLx+qnyRbLMdJ9vZwRvQY572XEftB3BiVRzmtZf64OIIafpFL7fKRmYoPCLPDYE1/zRUCvirvd23OaB115rYiM/+IEmAfGpMT20QsMJN7LcZvIaLlynlRWgcBOaVSoIpXIrvTbffmpSHiaNPsG1TDR6DutaQr0UPvcCSV6yYnEuaid41SElIcfMzWtJlVjw4F0LHHUVure7A13D91qnl+v8et6hc+Us8fBWsgIFF4nV6hKUuB52Xre0NmOLC4hDtRqs18mA+wTD3fVQsM0uqyk3B22WnYDvBk7e7frE6oQQrNNQd452PYGBwDNJO/TLNPVsUWSeTNBPlRBtbeMPfDCuX+3UYC8xV4XgqwD/V/A6bZJBBl4vnrzNCuq2W8Xk0bwGRKKbQByVjKkgPZaJ6P/XExmlp0M2ZOnFwO2LLDESVpKzeL84lFMtmAIdEhBzJFxEIHGyAhpGLtmN7VJkelEfSvVl8TBFIkP1pHzeQIDzLnm2QknH6iauoOISOUQThmGDQgQB0Xji3ctI60KYC0HuAtJ6D3j7RazccBjQ2FQz32gI9M41G6SdGQnB0LEShcZVkwoqeUBM4Z5i6o/abHxH8eDKlOcf+ETj/FZqkDJazDFOtJB7G+vt4xG2q6JWtdhVAbwbacHWWPNLx630bqwJzdZ7v0rsCcgPiOYqF200u/XT69J9ZdtPAj6Y8e759XF+b3zIX3Us4swMXtDVRXXlw5dYbZzZa4W55VMzceteaRimgymx/byiU7TrmlvNueReeavqHt5g+YN+1TU1PmeeFV7Aky43/n+7PsxJpl4QhcMRmnEwUQ4Rx0aaNou2QlaquAwED/oth5REzMG7C4KRq3T07a60ya6gYZnaYqi7FgZ0HBC3Q==","layer_level":1},{"id":"bb8fd4c4-918c-4926-b9b9-cccc592579df","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Subscription Lifecycle Management","description":"subscription-lifecycle","prompt":"Develop comprehensive documentation for subscription lifecycle management in ApplyGuard PH. Document subscription creation, activation, renewal, cancellation, and termination processes. Explain entitlement calculation logic, feature access control based on subscription status, and plan tier definitions. Detail subscription state transitions, grace periods, and automatic renewal handling. Include subscription upgrade/downgrade flows, proration calculations, and customer notification systems.","parent_id":"0ed40228-e6f9-4241-94eb-1ab69560f488","order":1,"progress_status":"completed","dependent_files":"src/lib/billing.js,src/lib/entitlement.js,supabase/functions/_shared/entitlement.ts,supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:21:52.5978793+08:00","gmt_modified":"2026-07-23T01:26:09.2148066+08:00","raw_data":"WikiEncrypted:/qtkhP4ZGxGP/T1P8fibqOUUIrHpv8+KPFmZuiyNRGlS5F/WvX4YNoNw/mLXlUXuCLoVTG6bO8RIYnyJru+h37sRxZuJ8nnCz0E7pxB3eLGWYivnT1pcJqMCdYbcL3KUYDqgJG9159gNEKcGWs9Xt3A6/DqCzp0eYKbbBKQ/YLaCMCDeVAKLXREt8aomrpLHlt/BWNYEYQrX1N4mgBMaChL/GbfzuKHqERrVAByojT67C0E2J80+6W0scYEMkigi7UzcvC1BSKnD1in+X0+RmIPF5iW7eBI83bDnSytJzXndxqp7LO6dfMVpB8HByEh5rW9M/vea173ClBEJv67591tMU35ZWQ7ALnRbuKriod8JTYN7F5Y2LwMHnD8HAZKJZbOm7Yk/x7Ih7axxsFKWEESp+kGSBda0aycVaRaTSAmK4KLEaK4kg3UGwC8f2EP4WqHsnW/QjUlR0x1VMI5RA965n/KvtGMQtrhsHZU8O1tYknloFLF1PeNz8d0DTKf2vpN+b4nyg5srzJoBKaRDH8ibZRpIGwJc9xf4O8zrjDq0jo/juOtZ41hadO8uGx/ZjjNi9v3DtmYts6bEeCCvZEQ2jFBAhcmJtevb/3UYriF58hQtrQyDQvR3xkTZWHUS4gV5sZ2V/Pzmc/1hU1N5myhvXD604H0ne+Tx7OGUZuTfiilW7fg73gUFcssLAuNo9rNoYLxQIB9E7y6uQZabl7uoSaBvyQuyKd2Dd7Op3EGBcAKuvjTbumT8gDETdW9hbHstyG0Caxkt4BbjF49eiY6mU/c8RbPNS7i24o/iWk9ZCU1AThoA62f2WrLx3Cs4nCeg2LNxnsNaPy+17ALGB/rsOJWzDI8XMFCmhfvTnKWw7zSCEFKIKcMtJ6vRKOkxXK1g1SUxExS2Zbvum5HiuT8rbV6WM3Xy14mttggGgPG34BRTUFaeyilYlx6npE+DOBJYMIPF3BkOZ4IlThmFEgZantSKqLJdieEjmz/z3Z/A3uzv2675rEPm8as3EPzV62X25zFjQVBO/wyFBA9/vdD/sldNSxQrMb9cJBsB6YZMYsnQwYFF/gS8o3HpxQ18oAJ/QhWBIoRVNEL5INTa0z46FmNIYMfLn24X5cMJFOkU4F9F4p4WAGlfDYM2rl5vsxKhXWkhC/8kwQwjI2XlfJU8y/wXivpNESfH1YlGXf3kfElU/B8OpZVTk6KlTI/sG/FuS2WLbHabg19McBPa37y75O9sruV4za6rxk7/UQs=","layer_level":1},{"id":"de0447f1-2939-4ffc-a07b-9780fb389421","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Database Schema","description":"database-schema","prompt":"Create detailed database schema documentation for ApplyGuard PH's Supabase database. Document all tables, their relationships, field definitions, data types, and constraints. Explain the entity-relationship model including users, applications, offers, subscriptions, and analytics data. Detail indexing strategies, query optimization patterns, and data access controls. Document migration management, version control for schema changes, and backup/restore procedures. Include sample queries, common data access patterns, and performance considerations for large datasets.","parent_id":"915d9267-a5a3-4ccf-9891-2071a4e7b621","order":1,"progress_status":"completed","dependent_files":"supabase/migrations/002_paypal_fulfillment.sql,supabase/migrations/003_trial_and_usage_ledger.sql,supabase/migrations/001_schema.sql,supabase/config.toml","gmt_create":"2026-07-23T01:21:56.5069127+08:00","gmt_modified":"2026-07-23T02:10:32.185517+08:00","raw_data":"WikiEncrypted:k7ZVhi6JOi0VASXSFH1PQVUFX/3qNvJNGcNHm3cJjewlFIw9YX2RU7d1qiILwaYYgZipq8VYXMyEaJok6eeV+kw06jN/XAs0QEV1dbZV2ONb5CLhfY0T3zXPY69EJxTg33ADBb1BEDpp+oHT44VV7rCoi0+WpMoOqATUqSYh6fQDMTuYgsIvxv7Cl2BWT44E0cBsMfOST6zxGOb/edi2K7f9xg7fFf7OtJ2M+DzAh91fexfKDnw0kaSd6UYcmAsm6u9Y4hDEsDhJ2JmMJUqNwmOR+PX5GXEFJOrCRGqlZl9U6VTEKCtw/jLBL8OCzRCH5QlFanHhVEDL5EH79LaJV3NtRExHgyYtYSYFi/5HJhQ3ojeSuT/1PJ7r0VSdHspdS885B0AmvqCuQ9k7iZGl66ug4al6DP0kPCoqtBMn4Fr3GKtak97wXUAfudoVsUEHK5hsZFeoueo3uAf7pDAeu8wMEqVHv/ROs7ng6VD3MgLtTCwVRRUcGjiGL6+8uAe/uJxW5QgdxanjLgHOrL4u5qDJ8BOJcZkubEBm8YLA3NowOZs6BGhHUh1hfTtS4ny+9Gc/LVie28jZTp5qdzsE9AuapRLdqVgQ11Di9j3dpDm6VoriuMVcb+M7dtQZsbziWy+dO7vQTdVDEkV6vloDKPaE8zDx307gYfzs5gcKT4+hJUd1pFHKLimHZtPr9DKeLB0XZQDzqSColocFg3GMu39ZJ7fzMMjcRD3PcjUBSepg6/pVe3sSe5+T0ZEste9KfxXpvmeKK/ftrjkYhDLVY9G2ngjTg3rVziiBVkPzIirXZLK72ZM551jQisPgtZYD/X0uY1Sjmw4wSmGaz2qUFP70dlP7r9P5F4L0enu00NxhgqUef/hV68Yp7VPb2DxRTZYRWAStMDuSKpw6uxisaW6jOBFkeU+XmsAF6LxTM8MBGyLHV1mvoukFCcewYhkFnK9pyfd2aaQgopYIvnwZA+6pi4GLhgOHfQb5A5jbJxCIlGkzeRxBVM6QgPvBVsI0EkXx57DfYxhnrnkUpHgG2d1acdOV1HzmyQELjn2p6C9ZqMX2pIWAD++OUhfDmE6zyEP/gyrd7n7QwgXsXAwUS0ET/OHYOdQpSNCN9eNgabQVaJdgolVI7w260rqvk/9qCnaqZSQsdcUAJnfbkKCxcW0V4PSfef3e6CquZNMktuvs2ilchWeCHRaxK0KtU4V21jLkgguGfN6CEb0qjf7v9EpCBTEXUWFoGV41DRMrRO08Cr9p0+u6rM8fzWuyeSL/ni76W0BA+9xvtw0HE0FkxnW9A+o63qnQ1V3ApMBY1NWWc7LKZWVG12iJkuJzQm9jIeqmOi6B9U7DRivbXz1adA==","layer_level":1},{"id":"613875e5-a4e6-4b1a-9741-8fa7cdd2d1c4","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"User Accounts \u0026 Profiles","description":"user-accounts","prompt":"Develop detailed user account and profile management documentation for ApplyGuard PH. Document the user profile data structure, account settings, and preference management. Explain the AccountPage component functionality including profile editing, data export/import, and account deletion. Detail local storage strategies for user preferences, cloud synchronization mechanisms, and data consistency across devices. Include examples of profile data operations, validation rules, and error handling. Address privacy considerations, data retention policies, and GDPR compliance features.","parent_id":"6545bd99-a4a2-45bf-acee-bdb022c420ed","order":1,"progress_status":"completed","dependent_files":"src/components/AccountPage.jsx,src/lib/storage.js,src/lib/sync.js","gmt_create":"2026-07-23T01:21:56.6520305+08:00","gmt_modified":"2026-07-23T01:26:39.3207105+08:00","raw_data":"WikiEncrypted:SmmNTSq96N8aZksVSKE+83MTYikxtcAeZEfcDk6CGcbm+bpj8BFWsL+mnvo3z1/ot5y5+38xk2JqfbHZJDjAkCd2tXEK0nVPomw+vQ0YbcK1E+EaWJyhji8iMbDXKvw05c55EH0zHjUEBESjYemH0FimBz5k+3T8oGbF2//ymHaOcPbuhiXEn/FqSy/miN5k3SqLevorB/gjHyE+Wydl+hsQe7co1siUQHoDteqQa69Xv6YWGnxrIOZHCC2usgazbbcA59fRQYlnIU+8KRirmK/+sz50mzdYjd+nx84wltl2kc0fKGrex5PQWMPSoGscOKeQvWHzJzf5Q1g1+kM0v/zV+a4lM3ryvlt9ONIumZyGDzElDQhVtSFcMqs7e2bow7SH1aY5du9NySpHfqiI9uVPTIyVYwJfJpsyNN6mwH5Vw/5KaBmQTZjdmcu/LMV5A105q7OrjtfaixXVTWXXkPo9+pVIY4dznrKkiR4M5TCZzQc2G7+ZiMGQPvcroeq5ce2JONxZjN3jwFRl69IgnYdTp+sTgSozcQ7qC8lgins8rUtnYXIXwWZrqZBpWD3dtFqOcgcLna32q+8aUMOhsrYD1JtkyauwjzmC9kEwM2z1ondK1NacQC1zAXNq52ikOY+erOYPyvqh7atiYWc9XzYxz31cG/b4iYjiyJv9IODelSvDsi2F1TG1N8sdpklqgWPGtwfgsmcEtupaIzxWNP1LnIaeSLEW3qDZFytiGBql+RQ3NJ+/FYpDM2SnBnwjoS72n7c8IUqUc4AVaKWD/AQa3UMJy/APJC3WjNc1gwOjwzAhPoYSBSAkTrN/nAU1tQROdSkvdWqO6YYwr9yDaAsOELb6Tb2mVGViaDY0twHpQgfSjq8vE02fVfi2PnzgwtZJ5yWnXtIIzCU4ncCsshhC3B0LsYNsaG8f72JJ0qy8Jiok6LoTYeW1R0xFBHCu6CtvlcmwWLknp3Z/bt/h6iKXlKoWRa/O5m0Bq0aV42W7khd6jWW4+aROa3ytqKesIyiiKgYEYuovGWUwBRZj94TUxWRQxkcfPKanShF4Dne5ZsRMOTDtU2uYfi3/w6u3t+7a/PbgLL5zggnIo+J+Pe6jP9wQ9S/2/FM++gPudci1gkpVCbwjoIZsbCsT8TG6pgkJcsSX+PrtdFPa6AtxCSemal0i5+DCBR5wCtkjF4A7zRoaRbdBsBS+6QDgLg47RnF0J4FWrcTW+DDL9995Po5r2zB4j/MwXirTHyYGItPksf4OMOERoNn1yvNZagwG96HTOcTJ9/g3dV09CcoLAS/MS1VaXltWcUzVWFT2fb9PQU7tuE79bSZF4wDBpSHkGnNu/kCB8R53TWQUoEQKMrKYezET7X/Hkc2FwVQMpak=","layer_level":1},{"id":"5c9da896-ab28-400a-9241-b2057092c570","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Mobile Development Workflow","description":"mobile-development","prompt":"Develop comprehensive mobile development workflow documentation for ApplyGuard PH. Document the mobile-specific entry point (src/mobile.js), service worker implementation for offline functionality, and build process adaptations. Explain hot reloading for mobile development, debugging techniques using browser dev tools and native debuggers, and testing strategies for mobile devices. Include guidelines for responsive design, touch interactions, and device capability detection. Address performance optimization, memory management, and battery usage considerations.","parent_id":"7ed0042c-9ec0-43b4-a5fd-2e4537db9eb9","order":1,"progress_status":"completed","dependent_files":"src/mobile.js,vite.config.js,public/sw.js","gmt_create":"2026-07-23T01:22:01.1318659+08:00","gmt_modified":"2026-07-23T01:26:40.8310765+08:00","raw_data":"WikiEncrypted:on0Ub2n3T72LCTbWaTpZisP3dCN9t0UaRlUEuxwLGAWzlE6/BUVt2AtsKc6yGkovCHhIV7qXD5Z53q9yni4boKQwmWgKN1GwQSxrcI6XTzAMQmyLKWtc5jUTCVnob+PzGiphnvonLIxjOJsWV5PxE4Ak8m3lDGqECLlpDLxo5lW6AxmNegqk3Ig97oxBZBa3doiNYaOIkWs2bqxAN2nCEVIKpJYlnlL2wdgfeBHBH179pjhhAchYc5Y2E2JUiwq0P41H91kjlM9KpYNJoVnCw8kiwkQxStqSAO0WBPJ+1PBfuULp2fqRvELcYAMTD2qNy3IAkuOu1EIBdH3xUE5lSngGXkUweb0po/Qt5gTTCjhAs9pAClms+cNYfX+8W0AkgZNu2oNjl4OAc8VlHmtokIb5o30lxb90KveyPyCafl/uDhZGC9ncUxuoFgeXa36iylir6eZ78tsJnsp55c6FIZ2Lt8V4b8iUIqUELpaw56Abc5YMUE/yg8wi044j306VbikhlP9slw6I+SAT/DH4dNk7lE9sBq3idyPRL0gmHYnRgUYB/HYL2VxAf7icLpUXRHtutBZhlJIJ8UozGi957faNr+i5/kYkBYZYQBjiRYRic2MlkxxWFndKzoDkrCh/XndsV/cR6McHE1vm7srFjDhtRAoRmMWYLTR03WCoqzvOAPcRk2kW7AqIqfDdJginhiRmYI/FlVmFyRgASqOhKaxN4bChHa1k3wccXaRxvt6PU3DYvpZjJP0kV1afPWTmWxVn99KlaYLPjtOfBJjFDQnzBknyARI/8uZqHnqMQTlGwkj4Euy4bZU4tYgMOj0SliuwkkBUfyQl4NbpZ1UuCnxK6mdnr65YzOrRdmNUHpx0UgaJo8QFN1NoFJ/Wzi/hRVyV1XOSUJykADPvf/etpHHK+Kt3/9WVECfubjakVZE6nspW//Vqvsd28cK/KHjONZZGoEp4rfbHsYv0ryQ9EyCjoSB3sIeEsPMz7gHENe7lv2WNZxdZ5KvKnxvCMYjUVVLLQHg0BRBsLWhjjYMX7XC2ZZ0GV6VEq/bA48yV8kNA8hWQKFP+uGYag/W8r4rvrTX9oUojxxhMHicX4neDA9UvvxmwS/JzqluggwMDyXCFph3SVhRhTCcwwpbgzTeizpEvuGNuouyn1vfxunEd3fEfddi7CA8iknaPtHdpG5a3Itzo9BaRWxhT3xO5qhntQgfSGRSbAn1fCol0Go1GOWi+KYmuHz6Rw2agBZkwCm9+bAo7BrFjpKW0VX09lqTCkHXIFiGhBbS5+AcZ2ez5PA==","layer_level":1},{"id":"cda46bd6-f210-4ff9-826a-1df0b3cd252a","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Payment Webhook APIs","description":"webhook-apis","prompt":"Create detailed webhook API documentation for payment processing integrations. Document PayMongo and PayPal webhook endpoints with complete payload schemas, signature verification processes, and event types. Specify webhook security requirements including header validation, payload signing, and replay attack prevention. Detail event lifecycle, retry mechanisms, idempotency handling, and error response formats. Include webhook testing strategies, debugging techniques, and monitoring approaches. Provide implementation examples for webhook handlers, event processing workflows, and failure recovery patterns. Document webhook configuration in payment provider dashboards and local development setup.","parent_id":"c870be03-f946-4159-9251-65e9a33f166c","order":1,"progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts,supabase/functions/paypal-webhook/index.ts,supabase/functions/_shared/paypal.ts,supabase/functions/_shared/http.ts","gmt_create":"2026-07-23T01:22:06.4255134+08:00","gmt_modified":"2026-07-23T01:26:51.7477313+08:00","raw_data":"WikiEncrypted:CXQmuGWiFd8u2IfkusypB0Hu/GJnlX0kj5ETgvigyCqTucc8Px4teFLIAnBUTSXfZMA/LdYMFleEbV8mQaI4Fm/wea3diKHVfx2/IKTBfq6JMvjT0QH8InavmBcKJJvU4p+zrmAYm4PlkR6orqFrMiNex963hBKN7IPT1m0sDL4cnozXZp4Vhyc3AEgOz1QXS4He6VUGCNf8YjlAmD0102yoEapFpriFbZaZwWdrbJsPf+OL7//kiVqZY7+uo6ZiMoa3jIYmSnjQucOdg8afmSY6PvAflFOCQ8cz5fyuKFEBNBPo3kSIx6fxz4pt8QjVf+sOIK8GsbOq9jGjQ+S/Qi2a3izD2Av5hefCwDLemkk7i0o4CwuMhihQj5leExSVB88P6SSpMFey5EsSHM97dtxiFw5lDIMNm13/s+X+YP20NYoCvLssUYkR42/L7OCePi9Ul1ZOnNbyvu+UN4vg7R+2dZXeq6m56CQZ9D+NA2VNpilCYvKAHq6Emwz0Wvf1oYVG2Gjroc+6GveHCIPcrvT92/RLbaq1CERSK7N69vDbi1zOXtyk+O2V9f5EbN99+QB5XFpLYxmV28RVy7K7p9Mej2HK0zRgoDLkNkYIch9jug99pD1St2xcVZsF6AMizPQYAVt7kv6DrT0rVwWuFnq5sDLI6PGQj9IgktXhoro/uOgZGtZQU2okhNfwYjTYZACJGxd02CgXYGCsDRr9JxkaygfcMOLbt4A4HOEp0DvsmqMfIATJBcTVD+dysF2ITAMpKHT+OwtTUXtMPI3F5FXd6v0FoqG3EjLOvddxTDXVdBexozeKWYcr4hY051+X/2DdFmsGF0HI9OzX+m46ZbDwPX9iMBw1CVus9mgkK/+iQX0AJtqZuLgG1McVjDqVcafM1H6HJd69rsFKICM1mb4UiNqPCzHn914AvAQdwV5LJ99VMii7Zm0GyCXKsCLDAJ5hMGIO6QCwakGVmKlBDO+cRk4aNCGQgPrLtw6EVCJ0cC1iz4buRmwPbnGh4seTv2iBEhCXL4RN4TzotcFN1OJ5RNnoCRWg5qFegF3sb6rLPt/yJknE+d8nBbbn7bnph/9/pu/oXK0KMI8qvKdHRSHSb7EI+nPHwC2rwS6zEn57iyVxNOvk9VvY/0Z/+wEbjZKgSZpsQCzvB5C/UcsuG6xmM5in271hRvuRWWLAbQSTiJdkIkxxhnYfaiVD9KF6YKTGU1hA9ymMsLllaqpK2TsnydRo/GiuB7a+GLe0XWxYDM0juF8w0r6EyBhV4Id0oi73IfCLb5blCERJb49l8fM28+PYWMFTU88wx1DO4MIrfU64KDjyKkfCy9mvS1JCmjkamPBSneBqzkRX/53EA5PcL1R3sXUfujaJ1CleKXCoToeWjAgl9HhbGk80z59yRYzg5xIOziUZpUxKNFwbxzMXSepsCXmpuwduklsH5Z7fOpFGwFAME6+vxj9ahI5+mHYViGITPVq7el60mAPC3eICP3P82ljjmvyFUI/4fTEteRrOmdHZznBxkf9NtFFWaRN7lPwVxSbOpDoS1bTQEIgkG3ORpo6emWk+g2cKs3E=","layer_level":1},{"id":"45e8d4d0-3fb8-4a27-bc8f-7eeeb40b92cc","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"AI Assistant \u0026 Coaching","description":"ai-assistant-coaching","prompt":"Develop detailed documentation for the AI assistant and coaching system. Cover the conversational interface, context-aware responses, and personalized coaching capabilities. Document how the AI analyzes user inputs, provides constructive feedback, suggests improvements, and maintains conversation context throughout interview preparation sessions. Include examples of coaching scenarios, prompt engineering approaches, response formatting, and integration with the broader AI infrastructure. Explain error handling, fallback mechanisms, and performance optimization strategies.","parent_id":"531c9699-6862-444f-8f72-71e9b8983826","order":1,"progress_status":"completed","dependent_files":"src/components/AiAssistant.jsx,src/lib/ai.js","gmt_create":"2026-07-23T01:22:07.3552974+08:00","gmt_modified":"2026-07-23T01:33:53.458164+08:00","raw_data":"WikiEncrypted:X5zqz2vbpxhp1yU3YO9qlF7VeZNCU874nAvgipNneAxhWn1xzSE2CjgubjDmlO3TPppheetWOVZRCA7yw2J3APh6w4pNruAy8lZ7v+zxz8vLlhJsziPUHy5sd/GjexFtZlDBVaBq2g2ATyMcCbY5yHMB9nrpMLYCsHMkNovtupp5rCsW9PfWViZM4Tn4NPw8IfevG8DMiGHqaBnY7OJ1YTHE11k7hAQW+3piNSo7HEGNka3k1/QlZBNl0aAI/k7JB7nAHnTOJjodAuHlEci2RayFQjUq7X+dux1C+9kOppiY6Gy+Z1tYI+05JlEwxv+xdj8fXVrjG2+rvTARRF26W97SKAEmpA/5LNg0LG1WfPDw2+fmk+Sk+T5Nnd4RL1gf+ApfA/ac6DrpEgWLYcmKjWcMvKlzHylovnlThTRab63Yzr6yNb3Ra/uIXMsW+Nd5RZJSjvc+OdjlzaFW5cKe41X2daoaZnagxJAxNbPrcavZRXuy+gv4gCOsB4BKysi+0OJsJagPo40GRJCqpB+EgOyobXxpek0RDLB/dVldH6nl+i1QscCSNv/UjjUfjZXQ6yUUOQL7Wz1+vhcJkvzs+moJxZum5yHbfpQk21Nvym6+TvNt+nAQCUCaEb30+z1NbBTPmmN1fdNhkwl4J7yrd2iZnMV4l+Q82xX4v2hrrRp4MAAoimUFZBUgDf1gR5C4mwQKJJgbiPKHHt9LOi7s3pp/l3uh1/9SA/mTbSbLAKs9YTsuVFwe7womiyxFbgAKMFIzswGn7XJX/g1SpZ8z6SWCg6V0Qji6Q8AI5P39pMKoO2pB5xHPsczJwVZQz/fP839xtLMwsDR1LA25HQeb2HD87si+QmkggfM418b4TLvZd1Ye2fK7nLSE90XLiRGrl745IGd3pTfs0DFK7WQWRDgSnKS2bMWEtY/GrZxCxDmXJbmyl90xZh30w9+gvRnsPtEz0UPaKRnUacIgx4qeKSsXck8TlHL/GOjw7VnmgH69gmdjg1dNKDdaaNMaAhAKm595p20g/3N4X2Xux2MKBYJcNKBveSxGZ1X3Zi0Zvg1nSIcp6Nb+Kjv4TiXvjXcfg9j+qMi1rWIvOeFih/Qv6kYeJ0KVuTOKmyQGZHOa0WNLomJPEqZ2qArPwugvKC72hr5azAUU9DldK5JRQdJ434THL8Z6eYIr00zHIlxD61EON4esKnPPaCyRRQRE/QFwM7MKKXt4EJFSV1H/CiJzcVzWUE4JKKo9yWcD+aHlvtVJ8Ghstje3iIb3IkJ0kSAlE1TnWxDRUMVNgNALDrnFyjVvvHFfOokkK94j1q0InGLh2FAyAtl9iuqCJ0QI7iqje/Prh55T2JMMVkQg38eEhQ==","layer_level":2},{"id":"229b9044-125e-4b57-874f-0f47e928aa1e","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Application CRUD Operations","description":"application-management","prompt":"Develop detailed content for application management operations within the tracker. Document how users can create new job applications, edit existing entries, delete applications, and manage application details including company name, position, salary, location, and custom fields. Explain the form validation, data persistence to local storage, and cloud synchronization. Include examples of bulk operations, import/export functionality, and data migration between devices.","parent_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","order":1,"progress_status":"completed","dependent_files":"src/components/Tracker.jsx,src/lib/storage.js,src/lib/sync.js","gmt_create":"2026-07-23T01:22:08.2114608+08:00","gmt_modified":"2026-07-23T01:33:54.0239054+08:00","raw_data":"WikiEncrypted:6Fw6zeKwEGma9eKCQx5Pd7VVkVXFuBwfRExHkchluw5xfiLZZzssZY4QJMGqyVKBhp3rEl/wzC/UhC1yVn+uuPkZqDfdwZfO1nxmlbwhTYfiS5TRw/G0jBBQE8n7LXR5nVZMcitxAzy0AAxUvKagRRi6KZCONjfBCacv7LUZ7bh9ocYGU7Boocx27+rs7KMHsDt6SnghDR+Ktniw8Ffwafj6trjvNVbZBfdqeEA0DB3vu8c04n95zt/s5FUivawHGGvuH3rpKCRJQepZqw7oYfAb5Sp/MIFNM1mJ4aAW1xWZ57fgQJk+qBA71y4LtNf4o3axZn/Z/dyfwEW+fFMXP5fgvR+qx1LGyod7JEYaWTHSuYyoUgsbzAARUjHmJJ7MgxH83AWu/KyURKlEOYTw2eeaeeXuQGQFA8zqJj+B2lhTo8VxBdn9qXVmLrlVOMvihHFkTwOUqUix3ol4DywFQBE6VWmRMaef4J1vae3uU2f9QNZrK3lMbOGd8xsDyCl5c3G1s4UwWQ3xvMbCnN3ULP6orSVmoiQ7zXAQSBUq8nH2fBCT9z77pAGPKYNjRUU1/7rlzx8MSCAelW3bK5rA6BXzCG9cIQuUJpFeP4x1m+yIoTJDAnJO+3Y3FlhegEE+2XuDcd+l6W4pEhswvDUrSdg1sXURxsCQPq7CzzvmuknsH5aem45nX7ulLMNDKF4hZmmm0cEBw2Y0VAfMhrW390mOdTXYIMzqaq3Lt8MP6+paPf1WgXBGmdmo2z21cS97/XpmuYbqda8iEH6ZGcD31QDoxsyfN4lioM/K0HUxGTzZptRGy5d2oapiOPtX+xCiGzq0XNJF+xlGvVrA8NNOawj1aWvCOWni+ss7yUocEdKe9zD81cMTzx4Lhh4NmscNWTkP48NouIfDxi4yAvMTY0gr518Hrj7yyz1GXjVMAB8Eq56STERZ6W2OPrMlPYwLFAUoRWlO/auxr+kb+lvpPRLJ8GVMbzI/zjtww4Bxv9UUe7RdFyajdbmkphzIIRAJ8a1cYB3/09t34xDM6EG3MWQu7RNbQOqe6jWZ55Kr03dvqDSrsjoH20mnPPp6WUwVACxUXeXqV2BzzfWu7Hr+UO0RVjuRuilynrImObgAM0hz8V/L2kH+cUvDPv/MjOT672Maec5d+DFDvMuY8nG7V06sMxTyPvRTtDvtV4Lwhiw=","layer_level":2},{"id":"035167f9-ae3e-4f72-98de-c2208cbdc93e","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Comparison Tools \u0026 Matrix","description":"comparison-tools","prompt":"Develop detailed content for the offer comparison tools and matrix interface. Document how multiple offers are displayed side-by-side for easy comparison. Explain the comparison matrix layout, filtering options, sorting capabilities, and visual indicators that highlight differences between offers. Include examples of comparison scenarios, custom view configurations, and export functionality for comparison results.","parent_id":"e847f4d2-fffd-4700-bb10-98246cdd7d76","order":1,"progress_status":"completed","dependent_files":"src/components/OffersPage.jsx","gmt_create":"2026-07-23T01:22:12.6853503+08:00","gmt_modified":"2026-07-23T01:34:01.9864218+08:00","raw_data":"WikiEncrypted:Jq96TAyn9Jh2oFSkcylJDY76ov11r8piITxh4yDSuc6QALbvep8Jof1ymG9idMEzaJsAqHG+AQjYypIB75Z5aRn8f68NFZu4FElNSFv2JiizqnxYXbDmxy1NnMfDY7qZdu+9YGhRrncx9E76lbRj3vbyIlDH5BFB0tMEKyrRBGmnoiVGWTFZbctMdVwZaz+vF1PhGD728rGcJFwWMp1uugJiGZtRpwK2kPOi0bmn0AaYfgiBGZfjED+lDqokIfz1Ry1D25pRNI0/k7n8JBDs3g8IT+KyKbDn+MCOSHoTSyn8hOT/DziwuhcArvVvYs8/CF2+XqlY1eiOHPhnU76ncnc8xdwILvIJrAkDeCOEr3ihjm1w/i9deRt/vqYSZrgtiMZppljBC6716cBt50aTNCLm9mWUSa4qx+nWu0yYRDsQh0njsuoCnsCq66EUlBSMfz3kQ/jpMqYXYbWv9cVqaBvB1GqL1jm5KnA1E1ZqCuFBdLj0o6Ayh9u1Yra+E1NcHSsHKf9QV9cZdwCWgmMVszf6awk9HWinDHlVp7c72ZHA0eIEJFjf4NbkqWcOjoNs6ak7Ad1frv5m7FaOhyZ1AOhqMpdzncVa6S5obkLOAWwSVcM6y+Bh59TEaYhV+p/wL75qhMxtbXLQ8F6wgfvytnLZ0zAXECOt9F20JVTHaGPztb87EzBW4mmGveghNbmdQGONxYKKqaRHlpTY5MYH/TvmF3BunpuEN3M8eLDltonKNa+g9ZOAaJcIix3l2fg4lBV88awjcxoHrrf2s6PUCQ575T5cN3CpjgTmVFiAW/L2aW2J0H4PhuM8bXDmRNafFxRd2gvItJYUSBCRFZfFGG8FC7CSSaLL4xESC0fYn2PFAkN3clErxxSVSp2VoPVrHq0C9iGtZAWXVYI6J6oByFLn8Ac0z2zqj+1Hk8ApBiiVFXx/RzMCIdqNqNb1olPpoaYNXBxvsmEoeijVdTG87HPen8MaXAiSOhBj+dMWt9e1XF8freSjly/3O3mZEpmNkrtJrZaHIGlpQZIiIjCmIkUTtw8j7hhz0vrJn+nLZ/nkTrqak21rMmxSUVLKCw2YmBLsYle0c8cIYn3v7vqdyQeq1ZTzPyznZjbsW9QjnEM=","layer_level":2},{"id":"01ffc783-a078-49f1-9560-ab6646dcfd20","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Custom Hooks Library","description":"custom-hooks","prompt":"Develop detailed documentation for the custom hooks library in ApplyGuard PH. Focus on the useCountUp hook implementation pattern, explaining how it manages animation state, handles cleanup, and integrates with React's lifecycle. Document the hook composition patterns, parameter validation, and error handling strategies. Include guidelines for creating new custom hooks, testing patterns, and performance considerations for reusable state logic.","parent_id":"15e41105-5f69-496c-a0c6-d162881bc0aa","order":1,"progress_status":"completed","dependent_files":"src/hooks/useCountUp.js","gmt_create":"2026-07-23T01:22:12.9632777+08:00","gmt_modified":"2026-07-23T01:34:21.8237035+08:00","raw_data":"WikiEncrypted:VrTOMK0P24YINQ3w81Yokf8rf8M1XZmfikf/C7aiMuwK1jKyHDo/H2wOdlEAgowF9bIHdjhNryWChZPfnn4MW93WQYBr+GZrO8J48JCj97tpX4dgXzemQ+M4EhYwD9ghjhCh0vYcSDuvJ9O3QD3S70vhxU+EQwe69DaCzGzcfwiSh4N7S7TyKige6p+X/nZMckdldowFF/aceRibVSl9HcoxEYu5HpNTE2lMtre33/zMB79SqqGhZYOB+6dhuMdg6sPqJompPYTAetjPad52x1CuRq57SB4rRn2yF0al9KobPOZwFuA/B6DVpCt8bW2rJvaHYt1AhurvHBmglUTSEWa2iSAgvIKHEjJjGsepMCflw5hUZrN4g6sDCA9BTcYZG2KB1HL8gASadx7A8tGAv7r1pkD/2bZhs6J08x4LUuPIHhAEh+5OuObwuE5nSeoZJ4E6eMSX6ZEHzPpMPGF0zoQvNGRt+IBmLIxhXnf23scyNOOLsol22Egw4aOxHgxomstXwaQ7NvuiukB2gaF/pVznK/tdvqEdQ0Y/ohwTQgBVPg+olkYbhuqxHzeDsyjzTbIyFZ7VuzUTbB2yVQ2Ah7onb4ehcHO5NK0Epv+z8uwoA7QliXUDP7L9/dRHjcKjgHCom6Tk4hVQq9wlJkz07yywKZRg6doH7/ae5YwUpGCGpwhPWMpwqQaBpJGlAc1OKCgmmxJ6Gpq6+qmu7zINw02hvM1M2UiUIBV2WYZfYR9KKpXxaLRffXRJ9Y6IkQmIgbWcNTUicpMA4rTQQemLYZG/ehirNOQtAq7VgB5DISmQ0julpC7IOseQikA5Po9mFHXu4AHoxG5KQZ5flpgCgHoeQbIU0zjz/wlpG4vSZY1OK12JXVM4imka8UY9LfnYI6hUlLuBLKoyyfbyCm3CHZaX2wePKKHRsHujZc754wBaUJWAa0dQT+FitjDG7fVLTiJ18725SevgLwf4l9VcqQ==","layer_level":2},{"id":"e8807cb2-64a1-472b-91d3-d56e1f9a3435","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Form Components","description":"form-components","prompt":"Develop detailed documentation for form components in ApplyGuard PH, focusing on the ScanForm component and form handling patterns. Document form validation strategies, input handling, file upload processing, and error management. Explain how forms integrate with business logic modules like analyze.js and handle user data submission. Include examples of form state management, validation rules, accessibility considerations, and responsive form design. Document any custom form controls, file processing utilities, and integration with external APIs for resume scanning functionality.","parent_id":"4e6884c3-ec96-4738-b40c-ddece5a2a3a8","order":1,"progress_status":"completed","dependent_files":"src/components/ScanForm.jsx","gmt_create":"2026-07-23T01:22:13.6910331+08:00","gmt_modified":"2026-07-23T01:34:35.3214756+08:00","raw_data":"WikiEncrypted:JMq2xgPQDMbLJ+LAP4f11gZM5lyXj22MjY8A6EPA4s/H3yF5vgGv5H2Rfvt3NlLxcFxI+NhNtiRHmSK1oPhrWO3hCWFeDKcJktedV4+ZNAcVVn5dqRE8cw1BnhW7fC0jp/Vg7yEpgH7olFBn4QnHiV0bmN++F1mBY3eonX6NHrTWbPynWJHScBrdaUSxtASySXvBg4iVz42Y42sVtAIY0pMSLqh9U8ChoINT49XSfPWKUfiUCZlJ/Nf1Wxgbw7QyFZjURO+17k2nKcFZkqCqY09GD36cxCzRiDpjBLA1NvYagdqEK9rjGfScWObLE0SErZAhXQKb2GFJU3zG2bwkymLMIP19UNKiBI+ztMhyRoHHEtbdpx66BrhVBu7BA4Cws7EPHKJiGCHo3jMu/DHvuMfB4/aJHhfua0gCEZWxkUsOrl+RRv5rwApfc6elP605yy9gt1zTVjyoKZqIWdeBPUTgZOYe3zq2FZE0gkVZATgEcwtwNl8W/AHd/YdvyV1LGqukt2CxQi5gyzK+JoVG0RpQtf17HNyv0a8BnAUqpHqj6KI0ZuWbfv5S1HGeGbNcQk80oTPlPtCR1byHDCIefScFSpD7dWJ2jH5VbMoNU5OB1hv5C6MhxJLU3jE2ujPdIZ73VAjv6V1HvVexRunpQkD1ScWKpFmhbmTJmGbw/We0789LDIXkU1zz5gp1xODnfpZadmFPKFx4JpELFxwKdjmxXmsi/n0UAFdYmsfBR7ydJ2Env0WwpBQq02q2/UolmxI1/g2oLXS7dtyXFDWf8EroCSMzngJ06JEubM2C5ejT6OT4S2Hy34ac96tDCyGoxxkq+zS7ToOqO39FvFVD3cP507pwDE6Ok06BRuqQ28BrRuyX4pBxXBFr1zmMfl8E8PZ1611sfdY0ISmp1jFHxtcmxXee/o2cyo/ayUBnbUykeLTHJDRt8HWJHP/LM7xdHSBDkB+ZtramuK5qqmN3lgqubZkHBYheFa1eMIfUoShVYO7I1JPXr9I3HrTe4G9lHxTsJ3h//9BpjUM1e20WSG7d2CuPPpFBE/CpV/SEJz/pNLtEJVzm31Lx97is/GPMXy9OKVPrTuJOr2Xua6ulg4ZIch/Ybb8aW4gnplU6SZgdXdMalG/15wKLuCs5M5H3/t1uZb0PMESUaXv3OdJNqoTRsUPgrCq6dK/8x/M0RTohwoc//YsDDy9T4QmNWu3qk9XXvGv0c4WOM/EHqJYkkA==","layer_level":2},{"id":"851fabdf-9e04-4bef-bed2-56b6ba65941d","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"State Management","description":"state-management","prompt":"Create comprehensive documentation for the state management architecture. Document the custom store implementation, context-based state sharing, and local storage persistence strategies. Explain the useCountUp hook implementation and other custom hooks patterns. Detail the authentication state flow, data synchronization between local and cloud storage, and state persistence mechanisms. Include examples of creating new hooks and managing complex state interactions.","parent_id":"bea14602-7013-4ae9-a2ec-8f0c2eb62a02","order":1,"progress_status":"completed","dependent_files":"src/store.jsx,src/hooks/useCountUp.js,src/lib/storage.js,src/auth.jsx","gmt_create":"2026-07-23T01:22:19.1405359+08:00","gmt_modified":"2026-07-23T01:34:37.7623306+08:00","raw_data":"WikiEncrypted:29DQGcj0Xkj5ar8OataJBBxhchc25ft/oSjDSUQ9oFMqkEmznfs18jsO8Qk/7qxOyzmw6WXtqMjp5xg7mxI4VZ63ztCMk6ghG4AU5ONrFFpnUdN6EF0tfCJmUbqvjIjYtdjKj6Yh05vZWiQ6Lc9OsiUWNl1WDd5h1bMaHZIPcda17TU6UrKq5tAkrn5NldHoBR5j8j2h2dSuWuu6DXo7oVmuGvO/aPvK+bZU+aeuYTxkpH15zNEHjQlQ7F0yswjOo2PeHN/FML6GaDXQ7TnKFrDO86ZOOQl17hJplfFbgf+4H0LqMBeIwizGVAXY+nZ+qZuSm4U5DhmsswR4X7x+wJJ0Juw1gYuBO7XqaGXNByzQf9fm4a2HbKi1O4kTaxLjOYX7nr4Nju9+F358qX42q1G9dVcDQPgOGlxWAoMgyhV7fHTghvg1osZy1GuzAnAcVozGgGV7AS/6uTQ1QJQPQqX0Z88AMqlVoAF+m7M58sNWj33aPA1hlfQLku4eyh7WANOGO3yry55a2qN/h89oxPcBiV0EBzKLEZZojIhAaD+b6G696j3EV0YL7DcN4SrvPJ/8ACElT7mkLTS+KeOIhsOp/O1sLQy0FoNlNxafb4p/v4hmcTPAdtw/TTLjCmeaH+fpQ9ruDwo2rL8qwUYD70LmzVFV3kXnTODperMFiHXKPZaHTiJHlk7JFX+S+OXjGZPGqFSc2r9iHNCsV78veEH4lkVpGQEZkqEPu3paqEsgxbrsDg5pDYJVGbCnyt4R0d9yvziJWEKOakfh8WvqzLdwA/XN9mXBbv0DP+CwQ120mmAmKNSvbYKSefxuDHtxRiI2eMdU2vQuJfYCAD/BAOms8CEfeaNmkHeYQ85FIbZ1Kh0OHxUlh9vuH6oZwcadMFrDDtyPLBrLUqrYgjSfkI6bSDV+Ejx6Pbe28WGPSitHQDcT/REtTpdPsohzJw22Y+cPRgQuNA1YA1hYmJXbgT93pFx9N32TlyTH0XzP/+sa2LQBpMCBQcy9jZyBI3dFFYXCSet+azODkNe6/fstalWsQTlWS4nBJDUYDl9TDS+Ml+y1XJrHbnU2BWREk6w2dMRD0Tfg3Jynr/lzcChCWl0l7FxOJ0YAsna0BOyigCWn6tmf5Johbfj4uVJyDXC5vwHIoxOQ/kRxGTJNBpET/4Z5jzB3g6nfnsFhZhpOfto=","layer_level":2},{"id":"550a161e-2590-4b89-9908-1f40dc9b5e66","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Shared Utilities Library","description":"shared-utilities","prompt":"Develop detailed documentation for the shared utilities library used across all Edge Functions. Document the entitlement management system for feature access control, HTTP client wrapper with retry logic and error handling, PayPal SDK integration with runtime configuration, and prompt management system for AI interactions. Include utility functions for common operations, configuration management, logging patterns, and testing utilities. Provide usage examples showing how to import and use these shared modules in custom functions.","parent_id":"b9cbb862-07a3-4429-bb2b-1691865594e0","order":1,"progress_status":"completed","dependent_files":"supabase/functions/_shared/entitlement.ts,supabase/functions/_shared/http.ts,supabase/functions/_shared/paypal.ts,supabase/functions/_shared/prompts.ts,supabase/functions/_shared/paypal-runtime.ts","gmt_create":"2026-07-23T01:22:22.8311242+08:00","gmt_modified":"2026-07-23T01:35:01.202386+08:00","raw_data":"WikiEncrypted:GiHoxvzLlRrvjoptv4KJz5LlzuLpDFhtGvj2+J416JoLN2kFag094p6VzTjON92OIv5mmhILlAM7OyBAsujNggcdIyAQ9quCDpGvAPDIsF8b69wBsaCUiEada8TcRrKDc4un3nhjEqNwF2kIKmum9QOF9Fnm93BCDcI6YZLR06eocVjUfVb5k29qAyM4J7cnBuLXXadqSFESVYvAIJPBpZOtadyaEArT0Vcl3G2dYbMJjdoVl2WM5qRlLTCN/v3CLsDYXnW555nMk7rgIlKNto+jjklN6+J9DDQt5rMh0/oJs6VwcTgxATyQ7uMr9PbXxcEOP1xeTdOO0ZcM36EfdMqhhEMUCdHgJHnDqMZguMgzhDhrhC9ISxKqlW7ZrwJ6h+kQgsdPtYnrw76ivHkJ0PsRv7m9Bpy6J5s0hZzTK40kUMYKookYF4M/op51DasDj9gHcfiJrK7nf78dzLUuiMAKpQjGAz6NUnnoPu1vGEwd7lLjLMy0WiLtcjZvoQhVOqhFSoYwySvQl+m0EjcadYjgpqK8xM8AYETTmH2BcMv/2DMbUtiLIhDfcUE1+yY3MU/BjvYPTPMBpaPCCEr3LlN7kcNf+gY8SlS5LQrVJzXWVTKcGMM/tRHwglOF1JDANF5nHbwcHtzWpPxZfQz6nNgyWPkaQmGBU+B3OE6CgIols7WzViJJgB2hDKncs8RaApKZrp4gTTRweK7QNRETEOmNFVoMTOwFNQF7W/omI+r/OKe2mH9kzKQTGeedUrfz6aB2v7jCLCr5nvz+aYfZp5wWOxhRAMGdUHi4D3vLMZxBeBU8JVS/EHdXBjPw8285KpqCA5+hQnEl63HMNrrNRlssBv/+GeArh8R4P9cNA6Ohu8zwm2Ddt2b/rLYkQBQ+tI7afzaoqn4yLEV5Y4wXTp3lyg7O9p8dajHnvqg6mLoLvyrUABq/M3L5SkB4iX0odM1h42+cR8ZdedW+4PeSF+OZkRLPN5vdnC3HCOtHPb55F+kQjFf4HZ3iba8ZeiyThSTXeHIsrKkhoUzQzzx4tq1uNk/QX/a2wE4X7hUxxMStAGodWq9iYmkXBbb4Dl2M9BV7ibWr+S0imaOOWvnXGZymx8kfwMt2vMg8JgwlxoFRI9SMQ1p6VsaR4I+X0Gm+ofTpCtHkyIu/yrkSIhUebEeEhcQeJsfILyDhiSCsVmWXKKuNg6fzwVgjaxEQmHppsYack+mJUoLK0Jz/EY2Jj99QMmrwvtKQ6tfoQBmNEZ6dt3svcgz7Br+/0x7dURGTw1bdeCozw6l4o7/JlRDXLRnad1CUadlggTVS8BzZTy4j/6Etiuh9Q4rwZe8cWwcdK3VxF1VXZkZOMCuyn2PxoTN+QrLdiiNATXExQ8gU7Rde9aCjCABeprDnwjBEJCOOPYC21zTpXRsnBYxhmwspuw==","layer_level":2},{"id":"c7fcbe37-a3ea-4e09-a6e3-e50d05951529","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Red Flag Detection System","description":"red-flag-detection","prompt":"Develop detailed documentation for the red flag detection system in ApplyGuard PH. Document the algorithms that identify potential warning signs in job postings, including salary transparency issues, unrealistic expectations, poor company culture indicators, and problematic employment terms. Explain the pattern matching logic used to detect vague job descriptions, excessive overtime requirements, lack of growth opportunities, and other concerning patterns. Include the severity classification system for different types of red flags, customization options for flag thresholds, and examples of detected issues with their corresponding risk levels. Document how red flags integrate with the overall scoring system and provide actionable insights for job seekers.","parent_id":"807ef1ee-e7d0-4485-9b75-741a4a80cfab","order":1,"progress_status":"completed","dependent_files":"src/lib/redflags.js","gmt_create":"2026-07-23T01:22:25.9927257+08:00","gmt_modified":"2026-07-23T01:35:03.7907202+08:00","raw_data":"WikiEncrypted:DX1teTwUVOfs35l8M2XzW8R1pDUpcGzeppyX6a1IyY/ae3V4whzu5o63WmHZdAVzpSFowtpZK8c+6KIxMqNUlO2MTKjNY0xk0of7fMGoYUN9nTHUerB9aw9Ef3dEfzxniG7gn5045gIA66taR7zhfjnPfIhsfKxpWC3O1XUWXkrP1DO8LaNosUuoSGmAQGq8EclA6pBJ1fccOkzDXX7byc1iKr/QW2wl27ScIyvDveP1zxMOjjjDUSrrhKocb3VfYcWilNOQ8fYgfGtWwZnrtC+6Gb5D2xCSVn7j0DScQ1/5TM7YgZPl6e7SyVK99DfvyQSYXVArMNDKfbWdZMe4NpZkx/JpxO2RmysPUSqfEK7Jd+BKhiLSoVyvY1nk9eaLlciDJY/tWdMaCFN6DsoJLRwzt3kYOQTdryMmIC+UpiwgKV6TWVt7oK5PRlaCZ1RC9ufF+VqbABUzYZ4SofmlTqXM05HlN1qJNnbwt1m9cdkWHKGxX9L0RIzBlMZ1yKtNe5Ncleww2G38b39ybThsecm+HhCrBTpb65TWVHp4Lz+OJx6C9cqm3ZWc8rO2RBWJ9EaIaxml9F0LVolOAwmBUJTZdCj8bVbOUPpA6/JAsQbfRqzaOs8zuHs4Ed9IXDhqReqmA7d6n/zoUvFiyxb6hTzF/Zplcfku/BpPqb8ycJ4L7HfywvF6sg+VoDpvdFHtxafoW0CLQjEWLL+mZiC4ULsEXQQhkEs92Eqsktdip5nL2DLkypnLk3jab2GBUy+9Jj076U6MmMfa+h/Y4p1z81+RWchKgpkXUpBAQNTOldZqgHWgI/MoqB/IS7EIsf62QgmlJIxObZ9DC83pjdsZ9f7lfPDsEApxdx3x8iP6yow919kT7i5d1vDKNxI8Y7Z6iRrzyXtpuoefS9nxSeq++MaCLBpVPZ+rUhlYpbRbdfJs+j8WhrB2eHEyMYTrIIyxNZUXURPvhQbRysnorWfmttTE2ZsqXH1drXVvubU+WiUWBi2lEeKOUc6M1jmd+XHmaNbrXt/c0om3lbDmIX+x6SnaQCpzAPnx7ddEleY+HyyyF7+jHGsRfZGBP0iTvTXwBSMvzhYqvNIrQVc9iCPYQjX19eHLsnBP7v5OQF6XfRdbQCmna8cjpjsKjG/1e3kPZzrz67K0ZPJHBvgTL2d/nqxKOs3sOLvhCdE4umgJhSfzorVzbmBH4aJChY5tZsEZPGS7E94p50qIleDmKWnSsWVpKUj8qdQe0mWj0OesZ8Dbj5HSjWgAUfoIMfQmyyoOKMTtc+9+jVBmFu+9v/QqRZlRS2lYlynEJo74HtVNJnmPCwTYJguADWL0kZ3In4bUd8jC948rAMlUkF+I1v+kaPhqVzSFuXDFYL6EnByFs9HUhIVdpREhg3RDBoSpToikeLskkt172bJrR5W8humc9Bn1908CtH6ZYOWYbf4Kz6KT5+NEUVol2QGy4FfTp+y5mE2xdgj0zxu7uYjZ2PVScZRIVEViCqrw9uzVca5keRd4K/ZNLSkFHBP2SLK94Wf2cMCuccS09FTM347jf6yxHHxLgQkSKJRE9nYc4ijLAcN9gVsnFmGIZ9guTtQCO+WD","layer_level":2},{"id":"40463b76-2f11-4b46-889f-ba610bbac190","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Tone Analysis Algorithms","description":"tone-analysis-algorithms","prompt":"Develop detailed documentation for the tone analysis algorithms in ApplyGuard PH. Explain how the system analyzes professional communication style, confidence levels, and language patterns in resumes and cover letters. Document the scoring algorithms that detect positive/negative sentiment, assertiveness levels, and industry-specific terminology usage. Include examples of tone scores, interpretation guidelines, and customization options for different professional contexts. Provide details about the linguistic analysis methods and how results are integrated into the overall resume assessment.","parent_id":"6dc96b36-07c7-4466-bd10-1f0ab817577a","order":1,"progress_status":"completed","dependent_files":"src/lib/tone.js","gmt_create":"2026-07-23T01:22:26.1371574+08:00","gmt_modified":"2026-07-23T01:35:12.2606299+08:00","raw_data":"WikiEncrypted:cAL17LMbbXnGyzjUaBsU6VZiwvID6LWFqKC3eSJAxtFf+EvK5/m/1AtGK1yF563wyEeEGfDCdlVPO0CWGqfehJahRlByFi3+MHigiW5K9MXkeUciKL0qtLY18A915fH7bB/AwAeAfSj2JbOLb8p05ehFt2yJZ9K5S2weasLJvtXhb6d+huqJ9OaXJVTiJFKp+hjli8mOzHIXqDeN6f+k5bk10Fc2selNNDwaCmsYn1ow7OztrH0fCKo32JFfMF8djkfO0kYkB1zudvyL1C40AK1rGEmM3xocLsQAnwBDdwdQbvly2sOUELtiNoMA5dfXuancVSjw/DX7pWv5JOXPR4wdZ8TfbC/oS6/g6eI4S+zrVuSXZwHnL+xGRT9X6DgETl8+6NbsdjxHja3B8/3c8sK3aFLO3pWYxOJQZUQHCqS6V012Vf0lp5edmWwyW6q8jZZXlg4Yj9QBQflTyf0jtGDWomxJNY1I60k0VOhE/REVdBj3N0Ou8YZKm2iiHHqRLjsvKqNyzHKRNRJZ3c2ufFYdu/CI/iXlDjAXMELDEQMT1quj/BvtcYS2QW6iVBO37NM7CYy9dlSpX2yxZ3BB5MnR8ZICVEP+b+B0juwaAOl5aUKnmHo774DQq6tgAhYctHWPVLi+7OS/o9DlePj3IrZyua5Y12W1II+zgCe3CnQju+sOGDlp2q8+e65/8n3/rpqJ+9/qDECeB149DQj1yZYSn5E+We/10JCNypbHVl46eAek4pDZcjWRxYymrY2NM79ucJSfzRQJkafgAVouM6t6MRLf0DhcBbbNmTCX/Guov3MPzqalOTApzx7Bpj5mp8t/p1PdxBgR23gqnjKM4JWDUgC0rfvxv1n3G2kOPCQhCCfKG2H5PeTgfNdfT5DJ+8n0L63VhKsPTzJsmewphhOn3LRD0oRftA6jsDHuK4MH0Bg53t0Ph5wamApncXREnFRz/WtNt6A+Jp7wetF4UMfLODbBf3G9UBm2imBtesJstyx8F+ZT6Xpsmf5nwHrgWrLtXRvRI18ORXyoeKIEL6xDA7uWaO+bRZawQ6vHq2S2xO4jChzNaAjNGZxeZFOF9BNINwFN8D9rQNJSmLifVVIrNpapSyX/JCyImfM9J58oNjZ+g09vtbGWHqwBqSkf9aCNCysxZAyJUA2x3MQ9GY+sY2xosWiT7/LsFJK/1AdYRoluU9P49AiosrYzPGPv2M0skna1Ykpzr8qW1R2F5f4mumj6jE8PCMyNgMHUu6s+o0aC79Y2gT70CvNVHL08SCXjgdmXTlGKMYhvrXyXq7tgHBb0r0YZ47CYAIbAiLfWtBESB0szcmJrXvhkOK6X","layer_level":2},{"id":"b905b7a7-7bd7-4340-aa8c-f7181b08b946","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Integration","description":"paypal-integration","prompt":"Create detailed documentation for PayPal payment processor integration. Document the order creation and capture workflow, including client-side SDK integration and server-side order management. Explain the capture-paypal-order function implementation, order lifecycle management, and payment confirmation processes. Detail shared PayPal utilities including API client configuration, request signing, response parsing, and error handling. Include PayPal-specific features like subscription management, refund processing, and webhook event handling. Address security considerations, sandbox vs production environments, and debugging techniques for PayPal integrations.","parent_id":"66e799e0-8dd6-4668-ac43-a4bd7c42a5eb","order":1,"progress_status":"completed","dependent_files":"supabase/migrations/002_paypal_fulfillment.sql,supabase/functions/capture-paypal-order/index.ts,supabase/functions/_shared/paypal.ts,supabase/functions/_shared/paypal-runtime.ts","gmt_create":"2026-07-23T01:22:27.4658881+08:00","gmt_modified":"2026-07-23T02:10:29.6998487+08:00","raw_data":"WikiEncrypted:GXZuW6Ju/tQOYpT8fsjcqlwtzM5eBze7fIc+z57WpmpoFKLvZYwmL9hBbVf2yF5YQu/blou37axktAbG5xdHw0brkdj2m5qk+aZXtbwrXtMGLE7n2CSWhRBC+QhJj6zRaHqQe0ZAQy7RohKH4TVUW9EUBBz/itFsGMzeCg/e1QQ8o4Lx4tSendvpFOFzEOu4Yt05WCXrFg8HU2XXnygx5VGMnHWeo+d+/vkuDP7TEoRjdwkZBjAelkSVV/nusvDBPHzt00Ff8tNW8Ki1sIpsqeD97/DqgR97OtW2cmYfj6FK1qx8oOL4TgJMB09K6zSuR0kJQg7YZ/MukexB/l9gW9dZfHCd2GL7W2mFc/0wTo20m1yj2Xb7MgHeIGAz0m46BKrQGbgmzl48Uyw6MPshmskRbtD+XZZhCajK0ducAK//4jfCPv+99XqI4lDFOiU47/r3QDwzktpcnuu2MrV5/BLbNMSDQ/DnQ+Du7zR+j0JlaIvmILonVqkdo90IBvhZ8eWAk0wHjW2q18ZbB77UG1rU8CN4qqMqlaXTuGCxwrIEatdKnN7LraVJsZol4uKeCvifjL9Qc5rzKEWdYrn0YTcj3/2OmjPMvJmEMI1s8/pDlCIqBXBL3WbhMB+sRp9O9xqb3yJgXSZ63OHpTpazB2MgBJfKUCwdAFHLULjIARWx7HyOYcmeyHHAHPIDNIMAIONMt3jRSkxv8IL8CX4E9AptWv4aDpgCHQf8BpjRTQyk/YGxjIuCC0QZtjjsqYoCsMSqBlunMiV8+3Q4o35XqZ2KiHBNWU/NvZqfWyWyZsMgzeKuoXlC1CA5Ck7S0wAaewJNp0jn9KkfVc8vNrNubb6xzmq2gvWEjPmei5QHdJTr1GH5/OncjZA/H80CKstvuIUEQvl9sNQCVAVFwxRJzgGeBHQoivNaeYgreatnWzR/JpWxrnCe7mZi6K2r/0dR1j1PnsOYqq01k7ltGBnmcPAUYaJOjHsX0xZiEoWmWXG4BLBOK3qImTLq2RNC0DrxyQEpkv996PCTu3y7dG8TvfpAxCFee/Rx5WnaXu0l8rWk8aQezWT0qPlOtI7BiEeZpBU0cD9xLnXg5D/oq4dlzXnhlhwghSaVID+zjUg8GKVHGkouQgkq1eB9pHJy8IGUsd5uR157JDyqCLMo+vh0axB88ICB/bR6v1IyIXz4kXBPgs1uFjxPGCK9HbeEDeW+FkLXNy0YqXqyrbEEycCNU3zcaJk64BVAl89kQnTL5l4itFxHetDZejH48ankq3v1r3jq2eKya6s/iio5EQLbQllTetBZhA38oKR/1uqcNqei6oCSY59X5nXfeuDmzjCEvDXkDoyho0Ini3l6CpTa89zP2rw289S5jvkNAliMCw1T3tFdg3kWQRKDWhw7DxYk3rrDfCyKLD4FpDkPRmGkc5NHMbI23T3ntTpms2xS2ozYuJ1zUWt0I5DN8RWVeYNMOxbQL0DQZECtmbjS6H8UAuYDMDngxUKGISbeiFmV2lrk3lszkT5L5JfQR65DLGznehFy68Eqg1+gJYJNsbavyA==","layer_level":2},{"id":"ba28b066-6e73-4f39-b54c-612bae202098","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Billing \u0026 Payment Functions","description":"billing-functions","prompt":"Create comprehensive documentation for billing and payment processing functions. Document the create checkout function for initiating subscription payments, including request parameters, response formats, and integration with PayMongo and PayPal. Detail the cancel subscription function for managing subscription lifecycle. Explain authentication requirements, webhook signature verification, idempotency handling, and error scenarios. Include code examples showing how to initiate checkouts from the frontend, handle payment success/failure callbacks, and manage subscription state synchronization between client and server.","parent_id":"45127b67-19f5-42b0-b44e-63fd3d377aae","order":1,"progress_status":"completed","dependent_files":"supabase/functions/create-checkout/index.ts,supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:22:31.9828256+08:00","gmt_modified":"2026-07-23T01:35:48.781163+08:00","raw_data":"WikiEncrypted:4hzunLRGn1L3xZmJ6tNxuqFUyy+Y7RIxUzTLC9eNX2N0orlUzSBGJb2cCuX7OaCEQZ4Sea9P5bqdQ+O44ERnPKJRCwrhSVfm99U9KvUMRS+UwGZ0uArksAs8hU0nRX0pApJl7mu4iqPGDrn/6NDVS8yvKEp1xEJivRLodT7DjYfGHkDM2Hej+EkJkZe5Ba/rqOhHGI9sxVIymEdV9M0UJPDutG0rSv5p65lWS3JoMEZFxKpVDUHn7hVj4anmuKTaBFWECGiJa/25aRP46CgJbfwYzfbUjWVrgv+5uXO55yLjRypJ0xMjj7ujrojascVnzCQgFou6yrZ5VKUajjBF5Iort9cvvK2vxCVPaFmmYY+O9uWqlUpxKMRDUWkMf3tdfcpcr55roq8ByvhHF3uxogVjRx4thGpX9BLnYCFIZfzjJJXMDyx7AUxOGKfqIPkn6BopQXMmHGeGgBeFKrLLsrBxxSiDn3WywrFvg8X77aD7ESY4buZHMICxn2WK64JYp2jX4hGq9JX7rzi2r8a+ezxSh1FVEervJNzYzpFMIZqQ6UAZFAzuMDwgPGs/OwOVE2pZJYc+bKyPD0DnpDYw9mLFmxzztumNNX9oe5Wo7bw4IYpEibgY0d95+Iz8Xo3E7LIVxWy+ONa+nP7L7lz6aCZ54lB2R4oLwVLngSu2SJQeStYpkahl+eZXiYDUNjMCndmuYG9N5cAh0XjGNSuRZNy4SQfyfjXCcgLAVfqJBHFPkA340lIr4TkeuN2HkFq6n3uurn0E/5yvdDROxogo7HtZeiOMzhvC1cYHZQhcvrNfIxNy6fm8lLFsf95LeIdZoe86hTHBQbxTENpPcbBx5e1FcBiaA8Y6PT7+uzCl3Ft+CtpSeB1UtM7OrgRxOxK+mtEAMNjd9wUo8vElGMxGi1D3pc3D8FEAcIsnVpkvR3bknZdralSPjEzI6QWsor6mzIbKvWX7LFRSzF7hntAbNVcnLnqMoHzBdyX/gsOxiW4w6Yy5ACSh9b9V7n4u7GEC4ht9BVOHtb/qHQbzcN3vyujhyjPRsAZ5GOK+FrV9LoUL+wJOYAvQMvggFOJr33+MKwWjxSoAnUHd+8OZ26+f9yLa1vbB7/28rzJmY2dyA4NzC/ft6H+k6UL+7yQ7p5bFdSi8q8z+EBz5kdP3PkC0xeVaNa6pAn1nSYOat+zTevzkEBBHEfd5REy7cbJg9ZT/zi1K6JFyKmwvvRlRHgBHuY7B9e4LXGYnu/rzMU8S88UTHFSnjZ6eOLCXSEopB1sb9dt0nfke5y0AMc80xsR7wkcdMQZ76zBWC7FT+DQ6PNjx7OUVaVrrhSHEKqPRobR6","layer_level":2},{"id":"fbd04a9a-1d7c-436c-838b-dcf4a2c76773","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Follow-up Automation","description":"follow-up-automation","prompt":"Develop comprehensive documentation for the follow-up automation system. Detail automatic follow-up scheduling based on status changes, custom follow-up rules, and reminder systems. Explain how the system tracks application timelines, generates next action suggestions, and manages follow-up notifications. Include configuration options for follow-up intervals, escalation rules, and integration with external calendar systems.","parent_id":"7da1925e-ce69-4e08-85b7-74f2aa2c5b88","order":1,"progress_status":"completed","dependent_files":"src/lib/followups.js,src/lib/nextaction.js","gmt_create":"2026-07-23T01:22:36.309802+08:00","gmt_modified":"2026-07-23T01:40:52.0784077+08:00","raw_data":"WikiEncrypted:JIVOpbk1etlZOV34F9CT0/BzFpvm4qfEmFJliYtYz/YUeODLZrBx4qb9rTt1Iuie1/u0JRQAnBvFcZtQptzLDfbqUFh4ARL+imiQi6rc280VKaddmJ94z2uy51fxxgTZNQWN8OdtUgsmboflWuulcdFXricNmE/6oU73K1DpBdbrBuSe/jwT3E8DDUOsHT0UTmyvoViVHkQXy6kU4AsFxaKByQVQ2LE+OEPhpmcW9xnsxuZhQsZWN7nS7zXbqsp4RjlXYlf4HrgTHgelzkBRrbmoMlcxGvTSHrEphvGJlkwN0+6UwNmoczB1MyjaFEAxh9TEt9zkJVMDk2R486dy7RwPTVveEUEiv9ZL8J90jXYngar/N3gof8FAuoB4OWvo3ASR05SRlBdQum0eOnIX02j1W/U7nUUePk6gVBMqd4m7RkB3sjiaEXdyt/3T4+434wXMlj5aJ5XatXwnSNcbmbkjV9b/Qe1dfXRiwu683/NmRrMhZA71cuNzGludg8/qSy00aPuxA6E5LZCwmtwoDxKd81NtUOwyxSus875GRvNIgeXgDOa+tP5Bf1vpoGZlxGwDsoAp1oxkKestImdOFhBsF0O2l2zj6C/iFuKqqMWC8rqAN8YcsAx53IPhjNOtnepskBOiz7KYnfE48gL9Gkeiw3wJsaxcJQvYjzSEnbknzzoh+nN7dfbo13X9TkOH+yzO9bqIw+wiNSS/J2B9HXJML9+f4hHuwXyLV9cib5o3aTQqXfXUaFwsnUVzqsoV20q7HuXReXZRMKHJPOamnyYvD3FEJ0hGYTSykz2usS6OLlzxjRCYo/aW9qGZq1F8khZSABiyf9K0zSte3riwkIRDOZaV5C+nNSu6b/oIpuL8l92oO/B0G3I9fzT1l253/7LLTh8Q224cqgsRnrNu7iIsG/fWjem5tXDS2k2X39J94HYwi4+OSxYxO9wg7lLrtDKVHs3wRHcimAJn0HHwmTh1f4QDQYwr+jGKeH435xg3e5SRlVU2xYhEqIuZIBz6","layer_level":3},{"id":"00c13ec1-dff1-49df-bfa4-0d18010f084f","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Webhook API","description":"paypal-webhook","prompt":"Create detailed webhook API documentation for PayPal payment processing integrations. Document the webhook endpoint configuration, HTTP methods, and PayPal-specific security requirements including webhook ID verification, certificate validation, and signature verification using RSA-SHA256. Detail all supported event types (PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED, BILLING.SUBSCRIPTION.CREATED, etc.) with complete payload schemas including field descriptions, nested objects, and business context. Specify webhook security requirements including header validation, certificate chain verification, and replay attack prevention using webhook IDs. Include webhook testing strategies using PayPal's sandbox environment, debugging techniques with request/response logging, and monitoring approaches for webhook delivery failures. Provide implementation examples for webhook handlers, event processing workflows, idempotency handling, and proper error responses. Document PayPal's retry mechanisms, exponential backoff, and failure notification patterns.","parent_id":"cda46bd6-f210-4ff9-826a-1df0b3cd252a","order":1,"progress_status":"completed","dependent_files":"supabase/functions/paypal-webhook/index.ts,supabase/functions/_shared/paypal.ts","gmt_create":"2026-07-23T01:22:38.8656088+08:00","gmt_modified":"2026-07-23T01:36:14.4222546+08:00","raw_data":"WikiEncrypted:lwC7d6wvFUcTMCQxUtXdXqC6eMdX1fOX9aAmzWfN54SUfC//s+EX8CcLLlpnw7oJJbhUUsZ+/pyuOUN/s2p0n0Y5rASGE1oHSuAuRd0rFQFKQCs/O/mFuZIp7CGGgivFUNHSLDXE1pc6eKlnHPnMLXJ4w6e0vlxgWrvvMUnSdpeuu1KniCmY53ptvlUMzlbDlf4rTjbYppPoDMQXGH6mfqfq/5VZOt5JxS8rpblM3VAdhTapbDmZmHp48HPMr4Y31v4/iP3TOYpF5aRNn9eXB9onBAb9/i2yOR3utU7R9IluCZyuZ5fOcmm+pKw8JlcjZGf6C7sii6A6tPc6/Goa/OgdA9HlLfRMjuTopDZRcc/lufeE+bEmEOn6ROVl6xdiVSkSwaTrY4Zckfw8Vy2BNadKmbxMjE4euhgTkP0GPwyBu6xyjn4YxtR3RD2pmXjGzYMgn3tNZSf1K4VW/d0cXj0yf5gQD8l4wMd71lsuL1HVXNQqDgRRW+E5pTIUkJC8z384P9fIFUfe3dx9FlQ5x5u42hrmELONVUo37efMIFO3pPLYqUFotM0DL7jYHUqKDrRCHTRoAbiSRnmENcnwgWkz54uVVgau8zBYrNHnJREsrxhmxVMenRrXTi9vTk+DhaHmHLeeXa4PH1OD6Kl0WtAC24llPd+rR6NsqUh6VPyGrlFkjo2H492gASFqKnlPJ4MQv2K5nC2lJDj/fJWzsBFgXe+JHNM/30db0/kfSsqgd69EI63vXTm4DTtt2j0KPcVNAL6H0NPqGfdMND9XsG9btsVuJwYzJif7sGnuJiIlbEH1uK4bb15uOjwDqhMrsF8kubkxvVcMadC/XWeC1u8C8Uy8skr7qdRl99JyfDFYnPGz1r6p3PO8hAJJwUFOqksc0rWyWLIlpc4astiXH076fN+tUw04f11G0+OtiTw3VRNdSjV4YCJqRiD8j1tajvXefAPsk/ElkB47uNVc26ZETUY1/NOucM5AJCU1je8OCOwa7ewwjmKY0jlJRxHwqe7G90dqQIEfg6Itq1wCBHWuZ9/KYRBA+D/qkOIJ0X4dve2UtnsBDOSk5FnyY3szuWLXIwjgfA7QoEoT88yW40HN/HQU4hqxLHAPd0l2q2tbAk0H+9glHBEIkmlrHmWCVQVsmHpYVDKK1yZ4fiT7Yf6Dh3PC/N2opApLIf8lJ7LWSGiViNkOro5G52IIih9nk0E7CvYK4yTZ2IWLbRxoPpoH0oZKqLt7JyzdyIdEhP+Ng/lhfz8C1r8mwXyY6LyP6CWq8bZ9Ik8wMIrFMUZ7cjmJTh1M3qSO77l254bNx0FQZMBORuGKZwD9+EaNLA9iHNU3XM8JsZz7U+3WsctZJlD8tdfF25gop1AXGiFL+qPB2N0+UdVoHUuu68KS8KnLb1l6FO9nMnfDIJE9YcjH16pBJIa3bn30mE0OQxPw5p6S4wwVSDzwJ6YlVXSiaKMvrfaUr8Xl2zaXPfQhxi/0ZHyYld5c+S4n2CCX0DtqxNVjiR7XQ5AOcpNjQyF2ny97eFKdnk5qXfW0sNPem50tp4ZZ9SIdlRNK1xdA/Yr5Hsw0o5X8b1vEuLRCAIvN2PNqPWBS2sqw/+5yuZP8Jx/hCYhqfPkXzvSIhwcV4KF0c4SIKzqs3XUOMiuuetfsWZrcv5SYzAMwA+UjQpbHuO0IzO4xLmyUV4hg1vI8Q+9LRAwaO4D3/+yfggnxTCsALLJ8qjWY92KFRWE0HFf3pWNoLEj2V3JP9MwM4Zdh45C9tEnSovXH3BPbEhcgnSklzdFsdh4yJumczsM6E5OwWwAV5VFzti+8mOjjyNj6zyokJFqbb9SuH3ziTCWfyqWd7C9JM2VShCbp/BFt24zL8tgTy0WpoOKUab8+8/31EW0la5FcsB6VBr9Wr+shIfpJrsRTI8WsLnnCfFlPZbvv73tjTgk/QVFNuogX9C44A6TBSd4=","layer_level":2},{"id":"8c623eb0-3465-412a-9717-f8413bae5ca2","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Billing \u0026 Payment Functions","description":"billing-functions","prompt":"Create comprehensive API documentation for all billing and payment-related Edge Functions. Document checkout creation endpoints for PayMongo and PayPal, webhook handlers for payment processing, order capture functions, and subscription cancellation services. For each endpoint, specify HTTP methods, URL patterns, request/response schemas, webhook payload formats, and signature verification. Include payment flow diagrams, error handling strategies, idempotency considerations, and security best practices. Provide client implementation examples showing complete payment workflows from checkout initiation to subscription fulfillment. Document webhook retry mechanisms, failure handling, and monitoring approaches.","parent_id":"aad58f1e-81da-47d2-9000-d1e4cd8b660e","order":1,"progress_status":"completed","dependent_files":"supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts,supabase/functions/paypal-webhook/index.ts,supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:22:41.5469033+08:00","gmt_modified":"2026-07-23T01:36:40.5598176+08:00","raw_data":"WikiEncrypted:4hzunLRGn1L3xZmJ6tNxuqFUyy+Y7RIxUzTLC9eNX2N0orlUzSBGJb2cCuX7OaCEQZ4Sea9P5bqdQ+O44ERnPKJRCwrhSVfm99U9KvUMRS+UwGZ0uArksAs8hU0nRX0pApJl7mu4iqPGDrn/6NDVS8yvKEp1xEJivRLodT7DjYfGHkDM2Hej+EkJkZe5Ba/rOr2OzSICgCUWAyQaNE1Qqn0ffFGKYgYxcFFSMK5lolwF9UqzrlPduo8Pb6UAbd1YzdIHF81wA7v/2S8lCkoeRK7Tb3zhDhXArJS6l9vK8VbP1EcW/pQsRZ5zWpO16JUSj3W//eXhTaOI7A/ySVjjyzVA6NOCeslmG3Z1amZl10vMVPK3pE3FRPyXY9hVDbpcjxF0fHGteiHZw5r7KUo2laNgCzjwBo3+04skNCjkFlRlVW/p56/WGtikXumt5W4HP7oTJaJlJMVFdgS7xp5XysfIT6ThCQSa9SwUoTVFkZgqY5KOK+87s6y8dR31WW/rbQnqQXhbuBWg28lwAvhEtn8iTFCKwlzQn2wq4f99m3yaEb/4hdaICq4Gr6UARPiK1u1f5R/ETGS2s5Q4O/MIPpikLwyvDwCwWVBM7FhVkgWFE3aRLleYb1PHwy4tu8yJZDJj/60FbIBZZEHXFJoCd8vBw5lvVcy0X3R7wW120hhtPNisC2ck3cIpQzg7BssKRAekAxUaOkkKgYAY9mirKl00Oca9fjIA4M5ZaTf4OoPzPUMSODoYdUc3cF/uuZaOwpn5yMt1ltSPhs/rDAbT05kG5++pei/ouBnkiMz6CuKwU2pv3YFv6hyrqETnkCYBaiQxJBaPb1I5pKwGYCxwe57Xw2pRLFxtLTkyFfOK5EMTdPVrQTxJ4Gp9prir6ZXylGRK7klE/x01wu1hPlP3deTvl89Q/OzUyk+3nrKHzTGNm7ysSBf7s2Y3xMHWYd2ku+PwjV8M+rwtZZIqd8f79jm1lOgbZ6M1LITfgZrlJ7kMUSc0tFnZyjuoQ2FTEE3UtaiaIQvcLYlQVQCe3Rg539Z8cWCEbcan2XSIRhkAzt9nTnw0yRmMYpfeiKfyh3IIfVaq0i3lGW0kEHBcVxjVgGZlG1LIxigMA+dZP1LPq+7LjNFH7Of2xzC93S5nc5gT2ciZLbUVb+AuHBL3Zt49TmF+p3w+T0tyxog4FQ4vcWKaLHF6qu+MINcKhEH7kVkfSPPfndJQat/r6Yc9EhwiJ9uQfpU51AA8q+Ibije2LWVUoBTya5bG5Ega72rIMSckL1mg0T85b3waBPpWDD5BLmXE/en+i9iRD/Q3rn269XQX25jkq/IQX0pRyI6nYMSHUKHnggZ340jbmwF4mY/OlZCd9q8xfnEsALAGVND1XIwoKCJZXrirlG7nNXHdtGMiSVNFe/bgP12JOZMmEqvOZpEtcVwaKEg1EVkbaxI1YZDNBF8592rZmfusX+kzTrN3nvSuP7cRLLDrtgOmU2blQsFcx3mglyK/7P2P6cmJKoPxis88gbN/vJ8EPHWKIBzcyjYdKz7Qvz+EbGNsGWwWavhiooTG5bV/7AzuUEb2pbgp8UDH9dQHqxjcfsodrb2uzhBEr/gHRVz+DgSa9f/hFZg1q03l2jilIiNntVXZgEpE2Rg5BCM+mAyol5TUlTi7KsI6UNjkxq1y737bD4oR5oxS3Unu4rAiQouz8vaG5mJd0kIPGvGxJNDSJ3MZvUMove8VTPM+hv/fziezl2+HV/BBc+++vZD3Akg2Qts/DzHo/87whyvCDAZX2SnGFpME8XuZ62IDagLw9nGIZwhQysCwT3VALfNHPKCA1IvkutRme5A7e6BDW9dIGYgAqC7ARypATtq21rKpmz8d4fewPw==","layer_level":2},{"id":"203e889f-a9f4-461e-8662-bf12c97bcb92","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Form Components","description":"form-components","prompt":"Create comprehensive documentation for form components, focusing on the ScanForm component. Document form validation patterns, user input handling, file upload processing, and form state management. Explain the form submission workflow, error handling, and data transformation processes. Include prop interfaces, event handlers, and customization options for different form scenarios.","parent_id":"80cd19aa-ad84-4b1b-b83a-8a34a7c03774","order":1,"progress_status":"completed","dependent_files":"src/components/ScanForm.jsx","gmt_create":"2026-07-23T01:22:42.7380599+08:00","gmt_modified":"2026-07-23T01:41:18.2492371+08:00","raw_data":"WikiEncrypted:JMq2xgPQDMbLJ+LAP4f11gZM5lyXj22MjY8A6EPA4s/H3yF5vgGv5H2Rfvt3NlLxcFxI+NhNtiRHmSK1oPhrWO3hCWFeDKcJktedV4+ZNAcVVn5dqRE8cw1BnhW7fC0jHp1LK0a6tRUuLstnKHtx3JhGMLd9zpR04JbSCkGw4gqoqjeWA2oPbSTNKgF83ibCOkl7UjNpIjcedilrFvPIqEXx8mNugZ77PUxQOI+2tJ2C3kZ7xHZN4JJLbzGTqTF3w0mzPpwk+foVMMju2vPDEAi9FuKzpLrUb9dro82Hlb8bdbGsUB6H/ZdvqZmm/t0h2PKj/hyq77tCAt9pgy5EFBPGsFcA3VrdyqWJoBbBSBYqeC6feJgcTZtBXDde56HkiHKm7zNM1n/skAYfWpqeqR6UTD71SqXCyVaghn1hsMI3Iv1QHG/ha3zcmUe+2QCkzTrJDyURxT/B2v5EtQLhWHLulME4YYmn2PvP3V+nv9pXy691402dlRnUkVDh8hIXxN7MuT4negOVK+AvT5JzWYOIgLNN41acmunX+oG4lPnt9bJynT423pZHSSkY9wb2k2xdNCq88A9fsTk71aCPSpQViwkq6JYOCgmrIL96IPLNjQHfjgLgwopAgNGAW7Ou0/rl39B/Ygra5tbaL/u917kwGxNVQiaQDFARlA4/GgPexXWjd3RTk5R93C5P29goD1aFUTOaZx+NWX5enJB8HAK4QnGyWB9G3Xw0bqsFZXD7RJajt8XPWngUk6c5iTX+YaE8tOmUL8w9Tz62qqqKbQaJx9vfUu19+8L2G1EHawFtvgf1PKXw3oFeZg/vIeMPvCxL6ZPu6utFMhtYjqrU7RfDYt9WQBXHKUBS1TSX4BPa/BQA/rW+Z8WmFewIpUuqpQlhFgoOqKHo4Tr1cChWi6DOxf7sbvzTcDi/OOYOlzv/tTQ6LF6BS8i+tYaERFn78x6jUUUIy1RryMSYzNB0Rru7KzeogJPNjBBpgGrlt/o=","layer_level":3},{"id":"672fcca8-aa26-4601-b5cb-90009d3ba4a5","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Billing Webhook Handlers","description":"billing-webhooks","prompt":"Create comprehensive documentation for billing webhook handlers covering PayMongo and PayPal integrations. Document webhook signature verification, event processing workflows, and subscription lifecycle management. Detail order capture processes, payment confirmation handling, and error recovery mechanisms. Include examples of webhook payload structures, status updates, and database synchronization patterns. Address security considerations, idempotency handling, and retry logic for failed webhooks.","parent_id":"ae6aa76c-b442-42b8-8ca1-b2688bab85b8","order":1,"progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts,supabase/functions/paypal-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts","gmt_create":"2026-07-23T01:22:46.6349784+08:00","gmt_modified":"2026-07-23T01:41:37.4847778+08:00","raw_data":"WikiEncrypted:4hzunLRGn1L3xZmJ6tNxuozSD1u6ON3MXr7ctoOasTYnjNbNIh116ziu3CJosZ0vVaUvq4x9A4jN9D2baXicg7j3yoqgTaDW/RctAXdOjhhqNLe8O5Bb9ep/2wu1JvfwNi6AnMMU9UJa99DrMTJUMBrjfN1xzSd6gO4ubYCRRyOHGHo+997FLgFcn1tNc+JNS/myocoDJEFuhPz6k0k4wXEGqDjWd1DiYh+BytZSxFD7D429SxXTOwzve1bmarFbYyc6mh7pbr8q5macALfjAvlm1cnbKu08jVmVBZBRkfu2qWhay9qpq04Uz32OydmugSv6l4wJGzKVZxp9hbJdgq6t4j2c5rgHnLhjfhYNTvJmWOjqSa1OkdoM3mEGA+3et3g49lbvC0I8rmwaZ1QKDGrxhDXKQKbpQCyJKk/i6dB+Ut0MxfnZU/7lRFu3i3uSvw/6A6v49R6Rd49SIWJuv0ASm63/bUvl++IU5YT9ig0k/AefbzCmYe/6BV+qfZqM93L75jd5LZprA8YVlzmfNitkjdW4gn1deCCS/0Z220bRxAeRrnuqwHTDImjKQqGuEYgA7rdK9yur7ca0EvXGpMXZfYqiA3zjoERIkZvYdPbfV++xPBHt3NvtDj9Mfnuyyfp/0eYRK62uUmddOqtvmCrDBDXd+N2ESQazsKC9okzc6nVKRK/uUmeBU3wIAZEHJg31OUddJcn+KizOcM4qXF5bgfi64N0qE17HbZri67P/vC7LIOG6E+mefYC4upOkyYjebp3UD3ubruEok6GMwbpyFWAul4MLXvnBQ6bJPP3iiPJAXwy0BAn0XQvjhUE3kBfntFK02fUIlaWhlTlE88Vx5Ppkzf1BIPhldJVl3HGqIvcdSEJVfXli5c27AC5B65WzgabydQvkt5patDd45RXddv7rnA2xGAUwIlX/Pnwxvce2iQ8/vT7QeV5STiLiNp4nRTM8jmSlioiGnP1kExI6lWH9Aw94NUV+iehoUsZMYsAfBvAKe7T5vsBbx8lo9e8n4Sx23h7xKTawKMJ2IxZbDcWWtJbiUQ6VCT/n+ZM6pG52NYlWdfY2vXWi7FCYl2laSvOce3NMfXZtyqyZ/nYr+1IYUMHlg+ABbLq50infYbDY/s2E05RyPbs2oxfkMcFNA0FzPPsO2fCODAanM0JK+to6H9ZTMw03IQUApkARd7hcN+8tcVzitCxtYK1GFE6S0xs8W5dc0RlX6Kj4cSWOiggorIIecR3CJ+Qf3gLJGJO5Vi1Zm7EtvXvg4qfvQSPpb1j42bYSg4GMohLTu3Hu3B3RxtKKytuVZYaGuOQwQTHhxYOMptuH8MmWQ4diWkpkfMgPpwXqfk2wRQxxU4QbrOrPzlhAfA+g6KQVgdFWfQqLIHQEQTH1xjsav7rR","layer_level":3},{"id":"c6e6b197-bdc6-4fc1-94a3-7830432a4abc","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayMongo Webhook Handler","description":"paymongo-webhook","prompt":"Create comprehensive webhook documentation for PayMongo payment processing. Document webhook event types (payment.created, payment.completed, payment.failed), payload structures, and signature verification process. Specify idempotency requirements, retry mechanisms, and error handling strategies. Include examples of processing different webhook events, updating subscription status, and handling payment failures. Document security best practices including webhook signature validation, IP whitelisting, and secure secret management. Provide troubleshooting guidance for common webhook delivery issues and debugging techniques.","parent_id":"8c623eb0-3465-412a-9717-f8413bae5ca2","order":1,"progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts","gmt_create":"2026-07-23T01:22:50.2757272+08:00","gmt_modified":"2026-07-23T01:41:19.4628077+08:00","raw_data":"WikiEncrypted:cX4Cq6ycqUrOaFkgcmNdXymKQWn19e6JkVT/QbTnFEoVBkbUlep38cQOdzBPe9EffihEv9KWBZf/Wg/2AvBGR6vwEsQZTh3fRx04hsd7SMUqIIaG2vH8P/RjrKA1cVxau5QzYD2aeOSc/m0u1rgJkGsCBrlhg6z7JxwOP2bcpZzgb7EGBa8amtpkprYisUc6qEqWASfEP54Bg5kyGYPCCxceCAF6IIkq0Nmx8FBIcU0wnOZDUSpXt5diZiR0y4GIINcg1eZaMp9H3ONeaFBViLQkV6C9MwfclmrG2cAz4Mp7E3x8t/u46xnmIGDSbKDLJXVV+KcQjBfpCDzuhP/K0Cii7d1yvSkGmSM7VSmSBXaY7NYfaVByAb7WlegoFE3JL5hjetGoOI/oNFeeBSBD5v4RfjmYuIj4sS8vPN2NTx/QHVLWODvleDHbReSC0o4XXgL+8qHh6GqaLXQl2/V9gQwclSrFyhjpycuD/H7Z4g/5ciCLzuas3bi3LS81cdFvs8OmWIwXmkX+gKt2W67q6Yfpoa/YR2Klg23/0BOWKvzEgmJE/Tr8gJReUZq6K4SPlCQXVHendGavK7tN08etC0BUTrR1VQ34+txr7ifNB5P+KJP6KwVB/D/GXnU2a33AQXLBOxo1/CBhiujqVfXpIKEqvssYtXMWHELK3K6UToF+2xoKMC43hDEryaP+sRjk6VN2umqBwZ52T0DPex6ZuQfMo6ONG6wpEs9CZ1TZe3jcplw0P0sOeBGQQpNcZ1T3oVsD84S9HBvz5HLKFGwncbOqUZ2Ekk9ewEYvvxMNrMGzAD22UxMQhmWbsEvNWC7MJMXwrHHZogceo56m1FqJJfi+vSGvSDIqFiJp1JcuZVO67sqg14j8ObsFzt7j2to85yGv+TOGQMJfSZW31TUBsK3Y6xcXHM3KHK9OtDjQ506z9ksM1z52uQflZeIjqWVX6L/qwEi3/5vlW4JU0WBqaYQyWbUUidMeg4nzJzrjdgUvlXyOuo51mW7U3H1tj3D6FjIx9DIdnb7nDYjq2c2BsViIY5ECLcXddSoH/wnX4nkCev4PnB54uB76e/xlZ51wC5itsSonEAuzffv0YwNELoAydKEORdiv8WtfURf1Ih2KjnP1c3zTuvfQ+NBqyi3x9cubmMcye4PZekbxcaGmXU3c/UHQIm7EnWerSFkEJzUUUzn7CZKualhLwRL37Q2IhtoZ3BOcbtBHLHWh2eNnZj/bNVcVCQ3qOhthCBzoxzJCZR3TLm+swN/fhHC3e19Cr8cPHE2vBaG/JDOdEBZXSYUFB3ES3M5zFRqRq2uc0Bsra7zMbrbh/z+MzChnbxwB","layer_level":3},{"id":"c283d799-42c0-4098-a721-2485211f7ac5","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Webhook Handler","description":"paypal-webhook","prompt":"Create comprehensive documentation for the PayPal webhook handler covering PayPal-specific event types (PAYMENT.CAPTURE.COMPLETED, BILLING.SUBSCRIPTION.CREATED, etc.). Document webhook signature verification using PayPal's certificate-based authentication, order capture confirmation, and subscription lifecycle management. Include examples of PayPal webhook payloads, state transitions, and database updates. Address PayPal-specific error handling, webhook versioning, and debugging techniques.","parent_id":"672fcca8-aa26-4601-b5cb-90009d3ba4a5","order":1,"progress_status":"completed","dependent_files":"supabase/functions/paypal-webhook/index.ts","gmt_create":"2026-07-23T01:22:57.4374371+08:00","gmt_modified":"2026-07-23T01:44:22.7609831+08:00","raw_data":"WikiEncrypted:lwC7d6wvFUcTMCQxUtXdXqC6eMdX1fOX9aAmzWfN54SUfC//s+EX8CcLLlpnw7oJyA3MqhwMNUBCw+xltfXlYOeikiQMhmuTEwuxscvGATYp6HgfUQlPWhdQNCzSDXxt4Gvq971VulW2a1OnAzFnL8qhdnHtqklbERNW+/ZfLHFRpmjfyMonO75XsrUtRnfUJtq4DTJtghW6O5c1ElNeMsr3U9Z0ItBqmza2SL6lZg1T3nrBVP0VWkH7J02ECu5Gu35ZKsMez4tLjcFvGKdHrcjC2TN04IK4b52lm+1BNXUEDdQ7PPayiZY5ntz3RYPVQZzehiAgmW4Awxu+//uhinNzrIsQ6zndAODi7wUdqLviwzGDFL/uvpnHsXvT0mLz9UTiDvmjuxr1Y2c60/5/s/SVaLuRIPEfKGy6Pxb8kifGQSGS53CsT+JDH1Vy8TluThkyasHOjltipQq5Bv3S0aodFdyGUMRuop9G5dXSx04nZ3YGspGeDKvBoW+kcesAE0EZmQLfTnmOASGomKt3R2McnHlwN8fZ4vzXXNscVvHyD0iKqvyqpK9TfCW1z8VOPC3WxAODCcR+dg/8xyLHTXhJg4N23MFv34nmd/dnJjG4GF3wgH+alhh6bSid2mVM915VQOEDi/ukaEXWgR1IhqSrJ92ipXwSW87IjSu8oy+lkOQr0HBSVJg2txfoNk3/etnfRme7igSKdGE4qg9L8XDroAVSX16wWCbWq5tiTBgTPToyyVCNN2mASRiVsq2V4WMtvNLB6P5gB1qZ488ZE5OE5majWUTX08Bn65gMxgnMrLSiE4YRY0BpKTVrlSMiY5nLys6cwz8aIJqYKgmZt7kqu4ZE8Y6bpGqZSB2vGhwRsXqVIRf9M4MhyV5L9KxMc5M8XxmyOG1pwXJT5NiTZWGHgvDywmEq9gy8dxv/wQLN8tDeVnFruPNNFkOCytFy0PWJpzv8SXlQ7inEXlA+eAFjt/o6B/eJCQkomkoLLQzY/+t1WfvgJUjwm0UlTYWqOK/vDfg3tjLOju/dJY5qdX++dnDkg6lkyS3ZkLbKkiJPNrqZRc//IBzlOmXWj7xiNJ5R0bLJo4eIIJ0JwVr/QMzmbqMj8sJ3GDNnesQzb4HHKZyfOR9oZYtY+vNuSReyiGZquR4+TeFDqHXlXDecKdtUY5IVNkwilLWK2P8oQv4MtIzPKjZHJyLc79slY07o","layer_level":4},{"id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Architecture Overview","description":"architecture-overview","prompt":"Create architectural documentation for the ApplyGuard PH system. Describe the high-level design patterns including component-based architecture, service layer separation, and state management strategy. Document the technology stack decisions, system boundaries between frontend, backend services, and external integrations. Explain the data flow architecture from user interactions through local storage to cloud synchronization. Include infrastructure diagrams showing component relationships, API call patterns, and real-time sync mechanisms. Address scalability considerations, security architecture, and deployment topology across web and mobile platforms.","order":2,"progress_status":"completed","dependent_files":"src/App.jsx,src/main.jsx,src/store.jsx,supabase/config.toml","gmt_create":"2026-07-23T01:21:36.3286914+08:00","gmt_modified":"2026-07-23T01:45:43.2097419+08:00","raw_data":"WikiEncrypted:EPw1VhZSv2AMLpYzHbCG5biFcgGMvwOBOVUOBtRMzXq9nIrsyT+EBefN3hNUPITPVarYYS5Pu/iqKKh086FV2DmKzq7AELY1ngI7PIP4ODjrBeiH/IOP11D50GATmKDxxUmzBPM7VBhrvqlp30623ZtzxfTnapcf6BlU937E48QiifIoXkUhp25en611woA8PwnprW82NgPyxFW8bf/1hUT3KUl7bEcP10bXNI2dhZowMWnKF4PXXFnRm/JQw19wf4JiGZIWrHnDWZm+mjSoAQJWqDCTH++5agPD8u7XzXB3vZmsKbLMrib79jC5SZQ6vsw3OaXMbQOJKHvFYPcvNzUedLnCwmm0YpBkPha/zImhfMDUWwsAzH/MN5mmZuOs2Ftl2sKRUPZJgvk/gxRShV64BfCcv9YU4NP7TKIgCwLQ/oVND4mJeDAsawWAKfpPcU4Av7rroBDMwiOhZVVQYSzmHYyFKkKjk31xj5by4hiE0K+FVIJ6Dyxx9n/oJC9fARF7SMjLMKTYMGm4aLShXOGdfj8BQ8G9a/Aw4Fsxhgm5sBOwYh1YQVthcltzd4HdpZH+7eY5N4IzJi1dOTkxdTR5vzHxr9FuMr6zgC1fbTYqgyxlypRB92OWXpQVGCiiIBMoauoepcunZyr+6dxLsK6XkTFRebUcHEihenHXOoDHoPu7VHhqtO+hwP7D2QRxl4OG48ClymCuWWj5k4bwKr+/8Lg3Bo2MyFRJl9exb9QE2CxOr0JyP5sV+EwSrMn3s/0gIaFOFRUfmRidDZlEum6ccWywONbnEmA+TLjXtPaYQyHU/dt4i3TvrBLvPLSFmoWPde7PzQgVcM1lGX96AVP+os92rkiBfwl98oAjY0+CgsQ+rEtuQHqhuW0W5UZjKjpZDKVspyA3I4bhMbVkEmGJG3srlty27Q+6IIPgJUoeRrLBmuocJJAxWwxTW0tbpOosgNFYVSGRMnHjmZdcn0tw1Ro2NOyEQcnQOkkv6EJIL3er0U/TwN9k1x/rE2BTtv2VyOIqIpPXJb8lgc+Q9lEUw9fBvbwkRh7t4EhAPaklT8oJCasPkYBCn561S0jdCZv8P1rfm0oqSw4iUN4y7wgr6F9C0xuTXoLRcZOtkzEoK/Fv9DVYXMM2YvigKF5i82qS2Fvkv9zg9wje0OQPukDPH8vWy6RVlll129I4Zvln4uww4oEOHIb0pICCI+NNglM1Qu+MvDe5GFiYu4N9Po8jBAWWKmx+lACel+6EkpRyrOa0s9xdq4V22/zgyORwY0/CzK8HTdPmvClXymijggeBhVy0MUPd36b63e27dnLf8/l06kZTAZzVu0p1kM04OPvQJm5umvFpljaMTQ97NrQYAkj2sMWQ2wOqmrg+YB0bqzNrsb2qr6nM94+YcT/Mzbu9a/vFQ1bAYp9ai12/LdmhKq9FSsaRlyD2WxsaGTHf4scJcGfPPGjK1+hYrX4gxXUqlp56Yo068zVSteApZmu3qCKjTXhW1AoqZ9n0xxJP/1dV8qCkXQUFmaN/PBzrwKI6SmFJUr8qJy5buR4nUQ=="},{"id":"e847f4d2-fffd-4700-bb10-98246cdd7d76","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Offer Management \u0026 Comparison","description":"offer-management","prompt":"Create comprehensive documentation for the offer management and comparison system. Document how users can input, compare, and analyze multiple job offers side-by-side. Explain the compensation analysis tools, red flag detection system, scoring algorithms, and decision support features. Detail the comparison matrix, weighted scoring system, and visualization tools that help users make informed decisions. Include examples of offer entry, comparison scenarios, and interpretation of analysis results.","parent_id":"564369b0-e95c-4c08-81ae-df1e1ba0bbb0","order":2,"progress_status":"completed","dependent_files":"src/components/OffersPage.jsx,src/lib/scoring.js,src/lib/redflags.js","gmt_create":"2026-07-23T01:21:42.2685139+08:00","gmt_modified":"2026-07-23T01:27:08.2852885+08:00","raw_data":"WikiEncrypted:uoSe+almcPogJWIumMMrXyyXIIfd5mIltFluOeaaz3cZjhG2oRSBklgfwlIIMVx+py7MB0BnxrDVilxlmVoEoccdASFOZNGsXo4guhlwhBSXvo9gUC1QgmKN93Ugj543y3CRVoVJ4hOf77OYP+v7Rh2RaghCpFhjsrZlYNzUjYy/l2iUu3CfYE+Nc13dxpiyUk0nSSxz5pGWZKDiBMQAUQeuG3b9dUtNqavA8e1JLJ5/jTGB8zBVr0vPl+0hG4fWH/gI99DAob74V5Owp8bfhLuvyus+nnFpeljRbL0jEluhWsWVJRNuLpW0KZqCdiRwuXjgHEdTg7+gatH3FMXampPVP8V9lt2xA0JK/NpISdthQhdkYWnhz4MsqJoMGgDO/r91fpRLGo6WMYQPFAVciTR/dxJbSOebrOkUiqlh+oQ9ZbYLfrcbn2AdhcxnRb618Xj8s6Aoa2juTk2yPhpHwVZXiC7IQ/Btlfp3hSb4idzKI19GHx3cl6ekx1inqSZgDA/0l2i7A5BJghv7NNRC/FWtAzqcP+T/eFzRJ6syfsqBls4oamLQVhhMcc9l/sL2NSKKEgoqA3HHxrZRvHe5XsT06PSCtwpGNOD2Im8e8ZfLpSHKKuHJ+1/TUpCaTQT/LzTZRIvS672/svSOwPB0FGlP1aN0B4TYuEwMO0J5ed68N31O5gnp/EQs8dL9f61657wj5O4IZZUEDs+jD486eTgbMcicbTlQVtv2YcweFQ2viW6++iEBugrA8oPaL012cz37us0jv3mA/GKzes6HzPUpgnvZDZJJK2F45dnZkOEj+1gpBhGmfzwQPLrnHD0oWXnfNqGkyG5jGBw2OJgnHFDPZaJDB2m4d9x3eDoXMToqGLn8iWCx346hns7TtXMyc88dHj0TZN6KR3uWcezEhZ46Is5Wd7FtrpDDhbVpylPgoCiZlzOfWQk4bXEPXowduv7bvfsV5j4Z/UoxeLWZvkzoa0rifgbNobqMvusqyj+Sf0YhfL52rmQbNXWmw3PVq1PSUcSZw/V+W9j5kwKYhX4IEqO2IhNzsbpARqULyH4U91t71huaOW5H2EcsphzWZkoHb64DF2LTanEJ1wwYj0IippXHHs/h625yDylBiYoiGVM5OsMJg2/usjkvKYThEHtc4d+AbJvTkc5L53von7Ggkqod+1Nucp3oD0dL679HGcDvw09swGcz6PRGYdvWHoxMgivWlMIn8N1ooCnqJOnh6HqzeWJNEjFGiCbzjME=","layer_level":1},{"id":"7fbc634a-0afd-4826-b865-d8e1bb486b88","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Styling \u0026 Theming","description":"styling-theming","prompt":"Create comprehensive styling documentation for ApplyGuard PH's CSS architecture and theming system. Document the global CSS structure, responsive design patterns, and mobile-first approach used throughout the application. Explain the PWA manifest configuration for app icons, splash screens, and browser behavior customization. Detail the Vite build configuration for asset optimization, CSS processing, and production builds. Include styling best practices, component-specific styles, and cross-browser compatibility considerations.","parent_id":"531def32-f496-4527-aa66-895ddc7ac7bc","order":2,"progress_status":"completed","dependent_files":"src/index.css,public/manifest.webmanifest,vite.config.js","gmt_create":"2026-07-23T01:21:46.2883944+08:00","gmt_modified":"2026-07-23T01:27:20.8384944+08:00","raw_data":"WikiEncrypted:X+chvTpGMuaXnCxQcH9R4CTvatJ1HLaoGRH/pmlD5Oc+yZ05tD2YyeVkkV4JVnvZ2vuajEzex8RC+YudQDiJvZE+joPyBKnilwjoxF1vg3T6ZEkfsEVSGS8iWNqe8O5Z6X2zGH5DXt+Yo7BCNe7/zyLQ3SsFIt8NvwygtiLM1P7I8j2Odf0h8yXdbB26StkftTrFOG1FFrcMLO/sEhNaRtjYMkGFeVwch6sBPCYOKAdCGK9frBp/xUPMt9DtDJEUdiiFCut37lLoVHI7xHdmswHPCyn8qDp0M58wO2E0YsUMKJze9apFjQSDakUqU3c5C3igrWUA9pKrGpLlzxmbrdrcrPIKThI6Mxu5rJlzfHCRw6bnTczgyh8IDZdPI3JYpG/e9goA2IEVlEMbUQxXb2BQ8eNnI1k1BZCGWvQEaKae1VJ2RMFGW3S7z0MwJ3i2Z5sSYIjcuVUKVikZOtUc3QW5UcvoU+7TETptSUnno/kFzwtnDvC5tdw7oEWpDVIrFI0x4x7WP41kAHglpcUFDLBdFST3GkUqW9GzeDTZTPQxc6C7FrQry9et+p3GWCbW2ygStSh67BMvhQpSasW7mlPXdWOIAimnNQVc7NpI+csGED4lEchWNtIBVtOIZ6uckGvLjB7iCXtjpXn4KyMAvGFuJeeiihL8k6X9ng8f4Qms8Vw3R/CWq0Rr+KoVnxCucxKngqA72MMv4wDtBKnqQfTRMOj4LPATQMne0zUP33ALsZWOL0KaQWWYXF8hVC6a/EzS5FdzOMv41yLdLn3zS4dsW1D6j+3eMpQnIk6951OBFudYqvFyw52a1dC2PT60v2iS39ZvRhHKwSPmA1I799E1A2IwVzOlfQdAjHG4tlTlW6Hp2YOoHdZ9L4cD2lBo6a6RTezkSzxS4W1PGkH61H5R01lO7hpjOvDbP5lt64q3ibC8l8I8dlEmUayqnELOSaqCXblZGUpXhaAjjjqcC/jdUcDlPl35l7DEAmZs9hs4NOE3RN1dEZdbINb6YYhlSXdg0Ic5iY2gzedNBcouoUYTF1itb3WbF5jxgO0RNOn/j1P5ap/Wq0p41CBXGxyRCAkYqLx1Ari943o0h0UXrZJyYtiDzQWVrFvhAFp7qfgjoasZDhdf89i4TEPVGsMaexXxQRQaOaSxbuYILU5U9OFck3z/t8pE9mmHSX41EuzWV2zVJyibRGLus3X4iU5PmE8wuNp2Q28HywRDkLYiTA==","layer_level":1},{"id":"b9cbb862-07a3-4429-bb2b-1691865594e0","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Backend Services","description":"backend-services","prompt":"Create architectural documentation for the backend services architecture. Describe the Supabase Edge Functions structure, shared utilities library, and database schema design. Document the serverless function patterns, authentication middleware, and error handling strategies. Explain the database migration system, relationship modeling, and indexing strategies. Include API endpoint architecture, webhook processing patterns, and third-party integration flows. Address security policies, rate limiting, and monitoring approaches.","parent_id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","order":2,"progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/create-checkout/index.ts,supabase/functions/_shared/entitlement.ts,supabase/migrations/001_schema.sql","gmt_create":"2026-07-23T01:21:46.772083+08:00","gmt_modified":"2026-07-23T01:27:45.2753565+08:00","raw_data":"WikiEncrypted:N3UbzwGjCC3xD6BrTM0cq1+ibJD9DO06/3kIFUntt04tJAnGDcGsMdaXBg7GCggxBYqgLU0yyNNdIJSlBAZC5aNz1Z8zZGirVleO55QpcqV8Qz83NksLKXxHpSXj1kdIPKyTAA/V/fvZJzXvt2ePObp/45JKjSw1BVNfr+OWBcFsWUF3tprm8TW0TD1YMC9DvDLPwiegGkwaekaSUyYYeS743Z+JDmw1kZxy3fMYXBqz79OpGpXzS+pV9nyVOJcuHDQijNsudz4aW7W1Ig7pnLGwcSPy+2VkG4WwbQnVn0k4c/RTvnsjxSnNZXS+dlLwY9Cg1ZpEPxIU5wUju1+0FaFzPSmOuF9mygE5ET/+WLVNus5a5QcQABpFzZQKx8OhxY1I9XSTmny8cm7rFUj00R8xaTgoS1O+RyfsYA8MvklW73KIsYUOYs5dUvrT8kQTeUpPzeBTj2urfx1ty1S5AHKXT3gDegNN0hV7Qg0GULjV6WIdvCatR8hl6iEAEjkIyKdm6OWlE69ZHC0HQm4S9E1Bh1/7Or30retQhcmXTw7loYIplPb/qIN+5wQariVKvKeSdqaUUYH29PPDBz+J/UDweYJwzeTQ1QM4ClJQ9hdcfgXO2KB+Eer5JbWqLg3ojkAn3GvxcXZ3i9JbiMqxUIXcQuxmFcfXN4V8vwjRumW7pHrCJzjE7c+LiAf7END2mZ9tNdniSxWdLYe7em+Ni1b8/DGigfOHXGZ1wxpFqXwU/AzP8ITGUTpYgtPKSth7G3w4GB2NgvE8Jyn0WUpPCLN2jCgpt9txEFqUbvXmUVvT0QgZL/lygPxnuTRsQtE4ioDLicMaFzUdlOjFRcUSvangaSYdOOZY5KIRGe2mNUssnkxYjS2FUNUj9R6kvuvdSJ0wiaqaKcad73OVU2fwTkSl9UGDarcSxTS3lYQV37RCkL90pv9QlIpd0ZaQFTLxfdr4eKkSXFLIDiLZMuI+MmPFg4cwN90RHRxYq2y9+L4jMLhYmhFLP7uvrfcW2+kPjPg2Ikiuk7rfZbmcN0tJsXksDiUDBvpiuUEkhsNimiLdfyAqP2T6oQgfHGWDDss1FzH595JU2mvE5RBpzy8YSA1pIuuuGPMfKva9fQyT2tyoXnX2oaS8DKpRzVTbWtowUxNNCg7RTEfwuoWCt7H+VXGPjmT7WsCT0gi8+ooFWYfOB26MU9UbtHqAEveASgdcnK+xymMp8Q51f8+qzEVqySSsH/b4NFOk4gaebXXhaCG5S7pVTTAFYYwoZ+4YE6QEMJ53E+Xw7Gq0QUdpGFAX2B0eVUKFTUcJBlLsAVKygVUVY6f7mmaQCvHsf55Iq9FplK4kgtl/6B6xAc6Rv2Y5gQ==","layer_level":1},{"id":"fd421ee8-b963-4821-b1d2-fbfc0ed64396","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Follow-up Management System","description":"follow-up-automation","prompt":"Create detailed documentation for the follow-up automation system in ApplyGuard PH. Document the intelligent scheduling algorithms that determine optimal follow-up timing based on application status, industry norms, and user preferences. Explain the email template system, reminder triggers, and automated notification logic. Include the decision trees for different follow-up scenarios, escalation rules, and user interaction patterns. Document the integration with calendar systems, email services, and notification channels. Provide examples of follow-up workflows and customization options for different job search strategies.","parent_id":"1968d404-384a-4a0b-82f7-a66bf82b925d","order":2,"progress_status":"completed","dependent_files":"src/lib/followups.js","gmt_create":"2026-07-23T01:21:47.8595367+08:00","gmt_modified":"2026-07-23T01:27:57.4594701+08:00","raw_data":"WikiEncrypted:JIVOpbk1etlZOV34F9CT0/BzFpvm4qfEmFJliYtYz/YUeODLZrBx4qb9rTt1Iuie9LpOUVbDIP3HMtFCxduwgOYB6pVH830mulHrVWSiHnKRz3tNFzz/Y5C5IjqMZ/9kpsjPlGbN5GirWJQdhkp+Q/VfiZFndflyzaifQQY3OGNQ6lxwW345C9YRlnHSgda6t8emlEW2J1njRir2HTmloEWLYyaDanu1uVoR4TCBICscyEJ4Q+l0v1TzRtwqPtlM5GBdU29bv8P4+vpwJKf6/BtkDD1QTpqFzL9/bKVE2w2jXBktwpVpE/pm8ocTweEDH7F/PBx+t97IAqN6UnUBFMxDisOVeIpzvQv66mvjTLF8BnyUM6HqRC1lV2V65M+mnNnpJiyr3qdUwv7gVsa3sjJrNQXVPPGh3jCeEaw8em8JDHwuufAvjdjUIVWEcavVaOY+tHTMkCYHhT+cs4csadS+SoTByjgbKin/JPxP1PHBVTlnmf70BA981zIMaDk2iHtq8e/zf5YbQnieqngd4V0qqtXwrNVx/RRu9IpalrX4SBSZPfm+Jh77Q4RhT1K7d6q/qe6dkMqpFu3GCXMRGJDMCjsxUMC/mSpC2eipmPmGW5nC2CvaojWJclA6ekUoV1arl/oCzBdCqlfaWtynqiW+bN32Iv/sNWoqJa/IarE9hZgU/ZufKa+s8DphnTTi/HVoWICZOVMbjkjkrj+By/Q+5zluXSeG8Wm3/LYXfO6K/8Py1HGu8wtBQvmRZcgcrVUeosYdKC5jBSsvbfp6gjPw8YGX0ZoFB7xvILaLAAKIwvtGr+aJ/vgD8JH1QyzdALEMVo8sjWxReQk6bzO4tB1ZNDk3j5ROps+cPmRzYtq/0NqKDzt8lMVwBUn5aDccdc77hNUrnAPamK4fGfhxgJRjkdCb6XE4S3v/uTAOpuZAv/2Iqx7zNut+rzgGDJBuyzZ2ADIObncbvhfmmdIAgS8jNO+GVuGom/qHXAJfq61F74+TWcBsZfiN0TMPT+7xDKiEh65V+02dlKUtY2VzsLlRtyKPPyqqZfuVsdafveF/y9wfTI3Y6gwkbkec4c7oZdlRXsi57be2Q1fpJuhKvgzaWo5nXqOcZEuVjuGU3skQ0W7Um6qZrLfrc+f4fmM+EDeAWpZ2iOwQUs+WKCaZUPPosqVGLIhY8xqGGtxluvYxzETWl5GwykfKUehqj76P28DfU7yd2Z5+UB5q+j2sGtD9mlnx7Kg2GNS+5YQ/uJAHK4XOv7ftnq3M+QhkqPqW60wEwb/isEaDrixWIL3ugOUvZF9AGBsvP6cZBhtKY28=","layer_level":1},{"id":"f8486f05-0d3a-48e2-b0e6-1567cc797fd2","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Import \u0026 Export","description":"import-export","prompt":"Create detailed documentation for CSV import/export functionality in ApplyGuard PH. Document the CSV format specifications, field mappings, and data validation rules. Explain bulk import operations, error handling for malformed data, and progress tracking. Detail export capabilities including data filtering, formatting options, and file generation. Document supported data types, date formats, and encoding standards. Include examples of valid CSV structures, common import scenarios, and troubleshooting guides for data transformation issues. Address security considerations for file uploads and data sanitization.","parent_id":"4c08a624-9311-45cb-a77c-0010b16eb5df","order":2,"progress_status":"completed","dependent_files":"src/lib/csv.js","gmt_create":"2026-07-23T01:21:51.7728084+08:00","gmt_modified":"2026-07-23T01:27:56.5010546+08:00","raw_data":"WikiEncrypted:jfiGld/9+H9KtUv+q1149Wo7OfdVEqI02Cf16DS0Ja8PaAiT7TgMjclsEAtqG3PrW1/nbH/EyBcunG3u6o7P8IFExGiMTdZHjhhdljCbuPBhJ1OSUF4ziLXHbOMIuxxZSnUNzwl+std7+LrreLIPEjj0jkldzDRbsNnKupKkhlXQBbdUws105fj4a6F8aeheR4D+PgJP7Bc4AHSnKZC1KxW6QG4pse27uMdjDxSoB/VoKj28BpKl8Q6cKvBQx9TMi+S6Ylx5ZBb91UGNxfedP8hxOAGQqi8Xqe1Wwt1CpMw46OBazLy9i1mLbnrqsQgiMu2HbNOVWO2KkVR9MzOaIaMpogQT8XHLgJGH27mTlyhwU0P9aXaJTagj4zJedYGAC64MGDhVbBEP4VRLLXemZH9+oDkfKHgXmWfAFF4PMBr7WgJ8qeaU1LDR1FrLofGpXM3vhSyavAJ+GBKHnOAFcdgy9FYwF8H0O7u//6k222Zrdetm9IEaAu2oCUGfen5NREUz+YeffwhivLw1uf4Mvly1wULQy3s+C2sMTs5ROLcaOUsVXUN21LIIo7r12gzpQdMuAp5K3scPR6kubEd2mdF76yBsK9qZF/RNgoQH9n5+UsmCNdQAfhKrJrefuRbc1hLms9yigjYQY+mXpSjVqfYFuSC+zPF3BOi6u/FybAV9dviq4PJEi5YULBHUguB+aN4ySjCyj4ZCVaHRDpbL7NuAZoSfiGbVCfM1gE2nWJZNV5U0lZFwtA94w8n9gt2d3gbVEU27Jj4WOzC1AXG7co8eJ7ATEzmOWoUu+5hIz9wReXWey/IjnyjQGMR08LIGbLF4oQzd+7r1aZrham5tRyoj+oc7Kx3S1izP3N/B+2BZiPHqdZKrqn9bXPB1/SGWN7As60fTdqS8TyfMi7cgrBpZ5SjEv3y7/c8MaWBNjFhRRCdvEW0V/mfzgrxmaIGTZok1Ohmc6YYsYhuZFWZln8qcVfmawFOshmVHT2IPquI53RR3kn750g7kjldWMdCCy2h9845Y27kVXxSMvFnUWeAhKcQs8WuFmt8dm3X+eSff71suKo70AectdoSS5jN+1ZjDrqCLByj6OhlLLMdGMvxynBbBr0YAW6jih8wGkVFI9R6SNSM/68BE/jSMXPiVYPuBwHUB16KuH1mPgkPCpdyTwpnNIWCyJozDfnQACrkOOVZMweirkYKzQwfRegf4t1XORdoc2hbyOU2ctxTsS2zTGMjkOC0jAil/OzSfDPI=","layer_level":1},{"id":"9488f56c-fc6b-4c83-9ebf-4f35ef97e05e","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Pricing \u0026 Plan Configuration","description":"pricing-configuration","prompt":"Create detailed documentation for pricing configuration and plan management in ApplyGuard PH. Document plan tier definitions, feature mapping to subscription levels, and pricing model implementation. Explain promotional offer configuration, discount codes, and trial period setup. Detail currency support, tax handling, and regional pricing variations. Include plan comparison matrices, feature entitlement matrices, and pricing update procedures.","parent_id":"0ed40228-e6f9-4241-94eb-1ab69560f488","order":2,"progress_status":"completed","dependent_files":"src/lib/pricing.js,docs/superpowers/plans/monetization/03-subscriptions-paymongo.md,docs/superpowers/plans/monetization/04-ai-features.md","gmt_create":"2026-07-23T01:21:52.5978793+08:00","gmt_modified":"2026-07-23T01:28:24.7587672+08:00","raw_data":"WikiEncrypted:KrL2QibOSZbLMlUoFPtX5KhsSPaqDpJvcOQPcBbVWXWIlOLPJMrIQaY7CP+SYHhE9hpi4MutotMMQkDAOZRqe2J5tnB7ZHd1S8Fu6MXgG6rdjUuz84euPHiqGq5zh81NGveqW2Sz2P72Ld5g1WNiLXpqafmzkz/vxXqVR+OlpEIQJ58ChsieybXfQOGlLQ45qIaR8tZSHzGd2JDCG7ld5k62e/1+cQf0SqRBR1SXq1og/C/EQadCHjtAy70UBGj4Tx9YoQNj99tX89RuxORGr0jQCIrkCbzbuOrYAiKshK8J9wLG6BXoahDYvSEca86PW5oRh3dqvipr6yXkbwzMbrz9a4UiW4dlHJyngJbWw9QYSEyt7N4cGNnb1kTahDCracv3lAzjfw6K3nkPC3KvVOcc8JzR41uoAQdVL+11VJL7zY70xT11cSr4P8AkepEfs8fqPDM82tQqyLExUiS139vSjFjHosnj415GpWIvB1C/+Bo4d1DhaelplMQEGGsghgwJw0zOht61XTzmbzlu7pXpitQGfyS9H4IWbWQp6i7UETJuMsgEcIqlKgHiYlU3KMOAEudVKtku90neJQOS4wxZx3/rrNGloCxlyt0c6lPnSYsK6C3oW+t3EXbjbFnEh6LYciyIUFZ7LxqSakwbkHBaPzl6sge9thoyYlZVYgN1kWOTdKzXxkphRjCU4OFkNoSRFDzdVB1kkE7Wsqkc3JoRfxkD+2HQQv47kvYWEZjSD0WSnu9sbG2YAgmJVISivUDrAFn1t4XdmEf72W7UGlTh7PomhlsKJRBJPD9efRAgdYIVzKvNxq2/JLcHKMhxiwJMCncE6aB8AUGv05L2/Vn9ttGWRGDw0QClW+PmL2KRlK7LQ6gaIH+ooPQ+TgrkdviOmKA2rRBRn3KXR37jvZjmkZy7ppDH7+zJ+0UpZYzbFtEQklVDRnb0l3CC37jXtsJHoio7TzI7hCylWoa1T9nZYadiT7YDGMN7WVJBA4EnSXVrLMxmkBtgzUiegVlAn31juv7Pp2RFOSqusOWkyVZi9X9+jmPzOU3zBu9pWWsF3XdBotTQ0Mx7oofl4xtSQWigq2CxEz9AhM+0huOSBMUklCgPcF+PF/ewkR5RPyD4y/wD1+0/qe3BfXgJFmOdgOMEVqZmp1jqEcaGvX5YeGPnhqDzTNRBh9pKz+K+Fbs=","layer_level":1},{"id":"abeb2b5d-488a-45f3-85e1-d7f8f2b83cba","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Shared Utilities Library","description":"shared-utilities","prompt":"Create comprehensive documentation for ApplyGuard PH's shared utilities library used across Supabase edge functions. Document the entitlement system for feature access control, HTTP client utilities for external API calls, PayPal integration helpers, prompt management for AI features, and runtime configuration utilities. Explain common patterns, error handling strategies, logging approaches, and testing methodologies. Include usage examples showing how to import and use these utilities in new edge functions, best practices for maintaining consistency, and guidelines for extending the utility library.","parent_id":"915d9267-a5a3-4ccf-9891-2071a4e7b621","order":2,"progress_status":"completed","dependent_files":"supabase/functions/_shared/entitlement.ts,supabase/functions/_shared/http.ts,supabase/functions/_shared/paypal.ts,supabase/functions/_shared/paypal-runtime.ts,supabase/functions/_shared/prompts.ts","gmt_create":"2026-07-23T01:21:56.5069127+08:00","gmt_modified":"2026-07-23T01:28:42.2864083+08:00","raw_data":"WikiEncrypted:GiHoxvzLlRrvjoptv4KJz5LlzuLpDFhtGvj2+J416JoLN2kFag094p6VzTjON92OIv5mmhILlAM7OyBAsujNggcdIyAQ9quCDpGvAPDIsF8b69wBsaCUiEada8TcRrKDc4un3nhjEqNwF2kIKmum9QOF9Fnm93BCDcI6YZLR06eocVjUfVb5k29qAyM4J7cnBuLXXadqSFESVYvAIJPBpZOtadyaEArT0Vcl3G2dYbMJjdoVl2WM5qRlLTCN/v3CLsDYXnW555nMk7rgIlKNto+jjklN6+J9DDQt5rMh0/pI9xoFOIG6syhGTxAJ3YFY7Oera4Nc/nJWSr5m6dyh/aK9P7hylU8s85jvMB5imYItM0EEwWOyKiMCwPZu+0bKs9/NBWrSf32XRA5NmH+bz7PbP1TzX5UPTgjli4IPE+YvMIGUvQv2NCQS+ajszrzTdU6DkdDD9PoHKtOkeblcC+cWKRJbuQdgbp5KlE+KIWyfJk0NIA642nAOG7OR0/D2ieuhx6dZhkGUDOSaOKU9kpXNdO4M3q++eIZF1xzqHNifi7KYmLctJGpXk85//51/0F2qZW+FrDDoJsWVyGn8UEoSYUJCLtIJ5AtBi3RsD88Yf81WjDCZwDz5xi7aERvhELYB1j9T/QirLGcoopiAnhzen/evXcrvLzVpb/wCHQiXdcxot4+22MlNMhGwrNsvcDQqA43WKH0JUSrp5NvvInKU/ZSP7dql+VxDILd85MJxMDZm0xAIOPiSv4lCeYTmeky7cVgdpWyT0A3bM1s3L1WiMGqiKiMxJUwHpOHDkXRiJQC1qKHppIcJQuP/k4CLOuPc5brJY3pKXvAxghjdDl4rk/m6P/rejBAQVqz7O+sSdg9p9Wncc1xy1NwWqELDsQl4tiNiE70yhTzL4VnmWrVRIaKJV6Ea+arM8aP51QD3QKRb5Vq1YB2NXSyEGI3Cui4H1gnlSvIW94vOL5yLAuTw6MzNr9s9/UD1HWKDDcjB4PT4Fcubq1p2uul2OZClIqainp1hj4lxX5tLwndJPJARc6FQf4/C3ZpgIQURfE6HTLR4rmtkt74PHjraruDQ/N73UoA9uG4+h0hxZ61kAQKNJRIaYC/tLGWSFRRLuloMtKL+x7LQJFn61nMvf/V606f2XfXUZSzRKkvaN/zsyplb35m+BSqAqnzzEIs36qC1GBSxTHLdn9eYLKresD/RWE75pJJ6GWfkQnpZxm4wYDJqebvBSKR0KGxMq3vJO5v9KcSJlnZ7KHbzP8IFsNTF66uMZYrIVdq3DqUM8Qp6s59VmjOm5Qys+3ZZmfFbSiiwKVFkNr/Np0hOwQTdydzavOLff7uP625nA5UcbzChWYaWDaRCSgwh9kx8x0U5lEX99iWCjG2rfUBH5U/UBvboEAf3kFCZ98KIWRroDTwGIflVoWO+z+l5VfjYpV44qDVZiXFpplYFy1p7N+K9ZNxnI+BNw8XwCffrmAAi411aaQ==","layer_level":1},{"id":"5825996b-9757-44f7-9ee7-76b1811047e2","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Entitlements \u0026 Access Control","description":"entitlements-access-control","prompt":"Create detailed entitlements and access control documentation for ApplyGuard PH. Document the feature gating system that controls access to premium features based on subscription status. Explain the entitlement checking mechanism, feature flags, and permission evaluation logic. Detail the relationship between billing status and feature access, including real-time updates and fallback behaviors. Include examples of implementing protected features, custom entitlement checks, and handling access denied scenarios. Address edge cases like network failures, subscription changes, and offline access policies.","parent_id":"6545bd99-a4a2-45bf-acee-bdb022c420ed","order":2,"progress_status":"completed","dependent_files":"src/lib/entitlement.js,src/lib/billing.js,supabase/functions/_shared/entitlement.ts","gmt_create":"2026-07-23T01:21:56.6520305+08:00","gmt_modified":"2026-07-23T01:28:45.0646977+08:00","raw_data":"WikiEncrypted:rIZNw1oyA1LKpI+2ODtIAQSdvfeYYTHxqeG3vQQTkx9bXb3g0edQA1NepXKkU5S7/w/DZB5s80TagLWlzjg6JzObH0tDvKngFUetoZ0Cks6CbN5YqJUUUHPMUpH46IcLLzCdslIEdxfApKfYtCKj5vuoHMLXTDwtYyTVGhdDsGQHMwjgJRM4eBov8v+y/Q68MDb0aHZamYb6GYo/Y+lU5Ws2zeE3CUcChYD6V43jaEMmIydn9rXC+u/hO7CHQIFNeyzGlObg6kNlwb+fPZBtC+ZV2JDSCReZ+7QSsrhmxOkMcUtq2Ry0sE9wpxN11QOGvt8Wf9ZmlovY7u1jBTH7d0l0AXjJbCqFOAGt7M8ABYNg4x3mSBPkbIouCE6LhBQOXjVxJwqVCtLk8ZKsWz2uRq8zf4sKFPn9cPvd1Z7NDg2fUf4y/j7FOIjKpL1R6q0eFrKQNGTNTY1EpGrQcvE2ZbLF63NzIiI5plucQHu1BQyFquRfiA76S3qdHI7a7xIfL2XnnEiTZdIPkaFHUGGly/fNkh327iJYUy+HXuFtQAR0KpNNpnUIYu0qDzPvOEhENtERx040+qFuUJ6lQGLr6sNkZ9WcfDPD8Kb28qwfk/83uHOS0YGyG0x3IQo1Ya68+ND6TtFzlBZbOtf79GnyEe3f7U+3TUwrjo6YlwYLVHNI7hy78ig9+318eLHW4kBsGdqSvxKBoEK5eFvI9W4AkEPZ4HJ3xwcxuoYf8zLBaGnUSywACn/8Vs/bGYRG286ujR2nWu5EUEQ+5ahrab+znk5aY7pB/nx6y+Vy2c5yq2fdVbDO09zahWhbYuV454BSj/wdP2VDnylMIZaDAGxGaYYsf9sLJsnGXEw1dnkBBBJqEZeoulVROH3p14m3oo+VfmPw2FK87Btem1FiX7syJEURdwVx4sqCMhEKGTAF2mmv1EHcv3dtVGf8fsoWZuAn7IRkg0y5/+lioe81NkIA0lGjdkBTyk7NhRsK2V6L6R3wNAnCt+Ohumccrq94OWQf9TqhSQ8lR3Xl5vZwf6XNne3oxb5qTHF7hq7dnhtMrlE6+NPUd3zBkpph/5JO8H6gTZJhVY4b+ProLQEWfUwWbbBgzyEe5vIRck6vpyvJOXOiw+emblML0Fu7iFSkVwxoYB8kn82pSeh48wXxuKOYRKWNi5b7imxQYj/884h8blnocUv/UvJW01Qd2IE4Y7VI8FEr6cszW6JxpEUF1/ddrI3jsaPQQB6N9P/WxEt8GE2MdBHX1d9g4NeYsXLhM+o3pynneH3Pi3RWFD9rkirvVGjozpQ07n1H36NsINbNVNS9kWRZDBlL1iTI566se14D7vlVYxfeP53bMtmEceoo06f3+MFeBMrpGr41tM7nrT6f/yDrEh/neX02x+WvFl5blhJw2ahU+5v77DUYYsUkgFnvbxCghbYbdPKOZb0spRlmD3/ZwdgnxdMQgH2Mgooi/yCIDTfTHxwKlTf5daIYGA==","layer_level":1},{"id":"008d7970-ad47-4dfe-acec-79b3b4ba24b5","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Native Platform Integrations","description":"native-integrations","prompt":"Create detailed documentation for native platform integrations in ApplyGuard PH's mobile app. Document available Capacitor plugins, native API access patterns, and permission handling for iOS and Android. Explain camera access, file system operations, push notifications, and device sensors integration. Include code examples for common native features, error handling strategies, and fallback mechanisms for unsupported features. Address platform-specific considerations, security implications, and user privacy requirements.","parent_id":"7ed0042c-9ec0-43b4-a5fd-2e4537db9eb9","order":2,"progress_status":"completed","dependent_files":"capacitor.config.ts,src/mobile.js","gmt_create":"2026-07-23T01:22:01.1318659+08:00","gmt_modified":"2026-07-23T01:28:56.7022788+08:00","raw_data":"WikiEncrypted:usOxbo1+QgnXqLT+QgfUsQwjz1CXqwH1Z5sX3ygezesFUj07YLmrHQz/RRFZSXcwF+B0DvLZM5B4nzSUdkceRA/82BROg0KQPIMdnzkGyAfVYytpiYjS2O5Lg8x86WXZKdnshmMulndxPDsYPdjSY3i921o1KCtFITZvKBCfRGpH5EMreRsu22J7mlFv9BBU8++ttk0o4YfHwYLZwchDScLRiWkpP0sIK6nxhL9PlP/ZekPlsCIKaQZCjFBmPgkrF5KlHBvuWNjJ4myPgTzKBmxF8R2iwbXazn/Uyi8VxFaUFC1gdiNaAlanCIi9TRSxbq343pKHceuAYzfYsbbiG2z9U4/yGOgjLzaxQ4Vszmtj5WWU5GFJ5eW5UlUiZ4NXbgG7DO8SGIo9tjQ7ChzUqaHKQzK97xqFcglKEemkjZ2e+NIox7/tJiaov+yT4QzWgKGsNBYTH5ZJqs6/mU55LlROsFwcg2rKtG4fmNGNeZfUekC1zEGC/rYa+msoBX8NCzvxypEOr3NmEJN3hhKAUZcooLkG4URDZFOoDkWVHDHNzsH59+uEy0pgPcwBgUQGh5kwu4ix8I93zwgw+BHdUc2PALAhBSbPnjqylwkGfy2jLLOq+edWlWZfaGeDUiZdzWD2sUgZoTuTN7etR7zWJpBhbApvgf3184CCS+IpO1APZoaWcuq2cVX4/DagP1YM68KVoe5x30GauXLcOvSOo86/8iDl9S+ql/skhfDScZ+lWpYM4AHTWEuNAOyrTsLLRrGy6pNOzSd+GWiG4gdaDQ2cWS0xx2Rdzk4FXB04JzsA5ng9uqypqPRvG4OGGeNsNyBjlO8Nq1oFG+oRGbQS3GJi1O4dtlUfDbnm2xfAC3xHb/i8MhGdSaWs7q8QzR1AMBmce6P5+//Xn8N+64ysFaLgljSbTswqkEsn9Nlq/euXnB0YaoqHtrkJWl0GuRC7sIsXuor9k+5KhE3eeXRANVLnMZfqxTnhesrWhdN0XHAyMa8++KHTs+CgKAUqjEIEBbK6IeWlCBYRX8J+vbbaYgc1aw1j7Sr544Yo99Kw3MgwfzsFYFnpZly1iW0DozYmQJECQLNBW5B6SACECA6IqtTEKrgJeYWZKm+68GSpM8OUr6t9njfD24hgat3XF1BxLKdR87LbVMT+NiMsZ4SfzqH5JjXmScvoRHvgIulsQGTnJXgIDhd1XmstyXaFOf9L7/krCd5k1GwcGo5kM/uX8A==","layer_level":1},{"id":"aa03d6fe-9ab5-4b24-ac71-ec108a0ee51c","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Real-time Communication APIs","description":"realtime-apis","prompt":"Create comprehensive documentation for real-time communication APIs used in ApplyGuard PH. Document WebSocket connections for live data synchronization, including connection establishment, authentication via Supabase auth tokens, and message protocols. Detail real-time events for job application updates, user profile changes, and subscription status modifications. Specify message formats, event types, and data structures for bidirectional communication. Include connection management patterns, reconnection strategies, offline support implementation, and conflict resolution algorithms. Provide client-side implementation examples, error handling patterns, and performance optimization techniques for real-time features.","parent_id":"c870be03-f946-4159-9251-65e9a33f166c","order":2,"progress_status":"completed","dependent_files":"src/lib/sync.js,src/lib/cloud.js,supabase/config.toml","gmt_create":"2026-07-23T01:22:06.4260521+08:00","gmt_modified":"2026-07-23T01:29:13.6811144+08:00","raw_data":"WikiEncrypted:KSAQ8lpb/Mt69w1h+FKNr4LTf+0y06OacgZyx1QqL7mKbSdZJ8xEjhniG5xMZRQTLqOoJnPA77rLJ0Wc1Q3UNi5u6Kq22al5VZB4CLmRuz3rjL7w+rZjYKPc9vlCfLAdfgSuVLqKyTgj91xzFSnZWLxdDFivLpRtNwJSoqkYJeBrdvK6MjLmwbz8nUJZCGlTwye6wSVxEATgvpPFskqukXfx7JlKCayiTAP9TRvX68vF83yaMCCQr6upZSR3lBS+0Ib+btO4PFLYHwL2bchxiXZpue9kBNpGypvjV/VeCQ894j05EVYjGHEDdRmcqFaNg+r5isLbkcG1fXAhHmkFzVMOhEDHj8U1gFPa4qVRASrnQS35MB+XvhjtcFH/eBVet53qBxprJhiasXdBzCHFA6S2/DT4sJQJe/IJQ4QPcQxjl+B+4G2sj6AvDD5R9YzFWFsxuFA84X1trGU+kVTfxDXRDiYrK0xwzcXVyuBhW1gA+QnqXyjhQP215BJVYH41voyZW2UGPgm07+hxmT0QWrGWkRJuk5D8qLXdFpNZR2yHf5BnnGvu9d8X04YZiVRZyHWZy0RFye4ZEQyXZ4gCI+JAA7QJVjRcCAb18ic5W6CPc9LcJMOkqs2kRzgoVRkYkgylsEjvz9wOz4gKkIyw6L/9tD1lX3vkCwyfNU4zX431UKopRih8d/Wvk8vZVTDNk6HbIW3puc4eBDbgAi3uODv/TGqRo6MuUc2zZeUIbkNAn+C/pRq0DQm4IvqXj+LOWksfZNShlk+35BbOUk0XxuSiX3WQQfP9Rdu+1XXwYgg1Qmggx/xFBl+0LpwZV3G+hU7glSU6lxxF+gzc7nWXpvVxpAPoKnzAEPFSKM1E3OVsrP29tOBYqI3y9VaS9Kcll8ogNyXGRKTUty2RFDryYCA8Io3bYn0hoplnzLPBmAvLGkTtSU/AsGk9lOwdNNeB4ia7tbTP458daBWDSGV+doSLQeeeFjIcisXovqZsvw/zukyDGC6Dv2ccr5S93H+jJ+LJ7BUtSTX/+tdVjkmWyLee2db9FsicqUDy5fS/NgQoPKRX4WACuU9W8NgpZfIokQnLpvDNOmoibFtnd4Ek/HmG/CExDIl0P57thMcY3s29j5wTaxyKXO5oqtvREokBJ68sg4a6eOqUkcKMBQwC9uliSWwtLDJLKUp66nCisdtlMsZ1gY58dXOGcjvAb2c2RqJCDobFt41g7MZacGxvMb2OjVFpphv8CeKQFRvecH2EYkkGay2j6DR5CoqrMpBphTM3P5Jm+umxnrdXJdm+dxknXPd9yTKNTQKFD3JeKtjU78QFR1SNWpBv3LCycyOhcuCdC65Xdlm2QW167lRLTvNfb1raSJw8omOkbROh8FUjtnunklc57ZIuehF81S5kUGoclZB24D1kZPzswKyhNR/bSOW7QJss9z3iwJolq6ct/fIBKcF94WCgtRderuXp","layer_level":1},{"id":"8de1bf90-4b69-4f92-8d25-cf65d00831cf","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Tone Analysis \u0026 Response Evaluation","description":"tone-analysis-evaluation","prompt":"Create detailed documentation for the tone analysis and response evaluation system. Explain how the system analyzes candidate responses for confidence, clarity, professionalism, and communication effectiveness. Document the scoring algorithms, feedback generation, and improvement suggestions. Include examples of tone analysis results, evaluation criteria, and how the system provides actionable insights for interview performance improvement. Address the integration with AI services and custom analysis rules.","parent_id":"531c9699-6862-444f-8f72-71e9b8983826","order":2,"progress_status":"completed","dependent_files":"src/lib/tone.js","gmt_create":"2026-07-23T01:22:07.3552974+08:00","gmt_modified":"2026-07-23T01:36:18.5254644+08:00","raw_data":"WikiEncrypted:cAL17LMbbXnGyzjUaBsU6b0/EcKEQCDzJiApXombER9di+4sB+pEHh4G0DtBx9aTgEuNR3Jh3aG1tkgY5kc+fTXbs40uqb/JaBfr73aZ4hQbl/G7JuHdYJIfms2MIs31zGn4Y9KR1VKFz1YNqf+6CgmlMdPW5ATL4HDgc9xdu9fpQB5afbgW1ZOXJW+eVc1at5xWbKjqBeJMZDVWwT6kWtxEFl67b3H8hBOv3lsheU+M09bMJANhU9xB8KmobuJElLcTdtKKWowZsZSoRQLBDeVRI/UQy0/fdgN1lvwiylyPAWjaWlTrrY9eeLjk3+fZxPp1/I5B9MdMny22uLw6dRGCvFCxcqlgBVFXQXm63S6bWuawY1Dxr/yhpHRZI9CAKznnYBKK6p80JfzioPatfhzE5kufgJy6CD0XDGBOB+Hjn04OL/ArIjmQ8ECwDTvHugF/W73QsAedNxIw1OXnfBt0kBx769r6fNApZiIr9XZKlRBic88h6qT445hTQLEB1LDtK+gZPJPis/33omkNUHHV8nWltpdDoTeVHyiY8LnRZlrypqMxlUnWQYmN+LWcixEfP3O+qjlamrpggre+DMu00qqzMh4PcBgFm9RSWSMlEW35jJ7SaaDIIuIrs7ci8lHG3k7jKOiFRvx4bd6W9vTxRlk+3C554bCjKjHTTJ1FYXRgbDcfaR1s9B39Hg8odA2TCvtbY3dgM/02onTyhSzZSmw4WDU325ixQLkXr0dj9KhNmaOYfyBiZfhib9DiLN5Y4XypIoh/iSnVEUGuHX8IRD3jVHihsyQOI+6g7d8i7++OKvyKGYjFQitI4nsi9Hs20uBr4KDZZuq1KwoQaJ6R3+Itb/zCcL1KfdGNPvuZ5e+hZvLAy1xkLlBUI8b7+8XIFw8sDXnzJFnSZUQdpqnBl/G0+mZGqyzbKdd0NzcFXcQVw7uQ6if/7QDWLAKVBTYUHFtfCti30eHtMEW9QoH+RVmFXIBovz/4B5NOmb3ABkTNUCzTbeSWRRvZNq3MzFDKJ0Q4WTrPP3WcebU5RVPkM8QVro1zF5mrl9LfKh3O8LGokxw8BViltdyEvqNkCUexS9P/hYLlbVKuUhCTxdIKgh3FKK/FPdyoRJUD+P/H4e0n9G9H5065X4Z6lV+xc9hvDUR57+jVCVKc5bgDzT6YObasQ9vbEH+/SjdQ1mcoCnwi0oaGDqkaKb6Km0bd","layer_level":2},{"id":"7da1925e-ce69-4e08-85b7-74f2aa2c5b88","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Status Tracking \u0026 Workflows","description":"status-tracking-system","prompt":"Create comprehensive documentation for the status tracking system. Detail the predefined status pipeline (applied, screening, interview, offer, rejected, etc.), custom status creation, and workflow automation. Explain how statuses trigger follow-up actions, color coding, progress indicators, and visual feedback. Document status transition rules, audit trails, and reporting capabilities based on status changes.","parent_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","order":2,"progress_status":"completed","dependent_files":"src/components/Tracker.jsx,src/lib/followups.js","gmt_create":"2026-07-23T01:22:08.2114608+08:00","gmt_modified":"2026-07-23T01:36:52.1987219+08:00","raw_data":"WikiEncrypted:RIfdD6bOTCP6I5SHLW9yzJSXqibpEXlhVEgfG4MNScCudU1f1nx+6OgfNW5b/sYZaq2htV/1MDU/MXyGj4pSxvxgwFBoGd3zOc5Atfa5TkJTg1YHxLMWeI5fiMYhpGH1CWoJ8KXxN+bnbIYXEDU5gIstHzpvV5GOUnNkFlzuRA7Xg7Tj2RGdKSyHoq/2V54b8gCmYRu7YfyISuI19WW9RgKjc3eOTaubheHSvR5pCp3uWcgG5HevLSrogUyiYh9uUTDV9QZtcBlAkYeQdTf2SLi6rtmB/6EOHfT/dwNEPfntRdsEfD9uB82Z+uCtX1OAWyErAol7vnV7O/ru5gfUh5iWQOVAlhIwIGSz29enkwDrkL80EsQx2NPRXVF26PLa8CK3jrSMBhPj+gX5ZmJPK48U87fgAlNaDbtvmE7Z6RA5decMook4/WPxwAE3j7V+4LFiekXj09FqiqutDzRVvem+/Rg/k2xuxLjZoUpzXjgXleigCKHTktze+NGH11jZzvZI5/WQi2cE9yWYp8kFlDEGO2Eh8zPTt3Uz26LJTADw7KJs63xPMMmxvvC2Wdso+4MpJfL2mV9LwY9AONtkgB7HT7vCIboGjOkqAcoPSIFXI7Lk/Sc/k8Icsh2wGQYiQl3QAlMw+t5Vn5kEPwW/tjKgiqYRLUFOgvvqeXZwSjXBYXOk0E+PzRZD8vnwPT1O8LOzNmDbOmrL7iuXCJXk8WNg3b8lgqbj/zTGbOcb6OY9Wk3urXaorOw2xWwjkhwe35v2A8YRPZGTGNSmuegy2KLnSyF0/YEqO7DjbEvyMiHbt57blchv5bIC3Tn33mlCBH1bTgTRIh+0koFCG4v1fbyfjXgmCVrHwLT9FWEbBShA/QgenM2zzP+LHFkigrFHZOLYXVaVPp/LaimqrJHV8tMAhWLWlHOl6UO/qclmlm8ETpJDVx0Lo4Nizd/d/mRqxuRfdfTGH0TP3aE/HBgAEsAROfpk1k/TjYYf1DV/rY+Hn1HMNXCpKeLdhTKQncLYtisHvwJicgCkTmqHR7jYS/f5hnpJ6q6tyjjmu02lToC4MnlF7NOCTI8l1mfGTNgqVgAbj04xvSSj7LJNR3sTc3hELObuk6MNTd+R78uybw4=","layer_level":2},{"id":"ef1d6364-60b2-4a20-8c57-32319bd3ef19","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Scoring Algorithms \u0026 Weighted Analysis","description":"scoring-algorithms","prompt":"Create comprehensive documentation for the scoring algorithms and weighted analysis system. Document how different offer factors are weighted and calculated to generate overall scores. Explain the scoring criteria, weight configuration, normalization methods, and calculation formulas. Include examples of score calculations for different offer types, customization of scoring weights, and interpretation of final scores. Document the test cases and validation logic used to ensure scoring accuracy.","parent_id":"e847f4d2-fffd-4700-bb10-98246cdd7d76","order":2,"progress_status":"completed","dependent_files":"src/lib/scoring.js,src/lib/scoring.test.js","gmt_create":"2026-07-23T01:22:12.6853503+08:00","gmt_modified":"2026-07-23T01:36:50.486323+08:00","raw_data":"WikiEncrypted:XB3PgRmgb5x8Psg1PAXkgQj3YytcipQZBqLncX1SOzXhtDGQh+dlG4/q6xAjDe/hk+UYCxH5nrmSfrTtqUx3bTR++p1BsnUqpM58H1atPExqFXT8ofwYLe+mTCepVBrzsC0pLee0TU5hhvi6/H+I9CTUdHjR7FaeiJZt/4mR7AhWbhzxYMySli27fsRpq85kI/FZZUOVTaSlbKkM4cmiCoaZ5VULr657b/PTwvGY8IbVahPUGzPcip+EPKu2UGvH9UTwHB44zo6Cpszb/SHtyIAtj1nOlPYcmio4JMiDRTHEnyAykxmMxNV9eYZFyZNOMwqLYXbNQizJuoB9M0d75BqpyfV62OIb2gRI/ylbIqLDAJZqo9w432vDWyeEo9i9oziHDDPJ5ar0SPIAZfziptywhTCOe8oty3q/XNR1Wi9Xt4NW3mJi6kvpHupiR/sHmvQzTcuGycURYUH04hEU8Eo43DwnGrd4LNZ3AcDCQyA/4tUhRDcXl8KbQ50g4JE8iJgJLYf2wm4+UnFYxSfYLrAIrDqa9ZIruvS3WRyvBlp99tsaH1gwQp7JSiWOYf1D1wnc9fnSTewXB2PRRsy9ujmoLVoD8uUBl5u8nM7XZ6/DiM4yuS0syVHyl5ALpYpjFNRa7V3nSo8pxTXo6UQuynyg8Y0OUEQz+xdqboVhin0Z4pu/rgFK0SFF5UX8gPmoue32dkzuW45PUyKFJEwtQ1HGrHuD8uiSvlAoVuUNoYVdcg1muNnJFYetxnq3vqb8hD9Uu3IhXldmrQlS0i2wc4H8PkYkE2I0SpMrJ+f1Yt1UWqbiyTrGNoTaFlsgY9UUvbi5pYLEUOuQCsXjH5/042aeMuSf6WNN+UlbOHKqZ4rdOyzZhZsK1CJ51LPPewOxH4T8kNh5hI/epxqgEqSeFDAgbD/XF9gFGWHt5t/19pby6gBwFvW6304/m7+h4ot+iMeE7KlKs1f41q2E+BI4UFrO8c8TsuYVIiav7Z3EhX+/Y5gUY68CGO9oUKxxI1ihfgkMpfwBFhF/Lwi7BkjI7TgVcJ4DS7qfbRGCgjfT4z/r8lXDHzRxz+H4eov8UAFRwKdPmljz9OWABzPIjd0RoI6CB230ewEZ2tWc+6y/Xu3RD9hOQ7WTqZfdXVRUspkEZqHoy0Ofv8pjDErUIkzM3e3kILp4DVGG43IpQJGCqS+tnrD4nh+B4Ab5O14un1I7lHhMXm76Xf3mjyEykZGfubG9p86LQxru4knhcHUw8/qMNIKIiEsTn1s9q6hgVc3bQmQWTtZfpaWP4AK3Gymf8g==","layer_level":2},{"id":"bb446a02-b60b-47a3-a03d-542679dfc768","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Local Storage \u0026 Persistence","description":"local-storage","prompt":"Create detailed documentation for the local storage persistence layer in ApplyGuard PH. Explain the data serialization strategies, storage key management, and data migration handling. Document the storage abstraction layer, error handling for quota exceeded scenarios, and offline-first architecture patterns. Include examples of storing complex objects, implementing versioned data schemas, and optimizing storage performance for large datasets.","parent_id":"15e41105-5f69-496c-a0c6-d162881bc0aa","order":2,"progress_status":"completed","dependent_files":"src/lib/storage.js","gmt_create":"2026-07-23T01:22:12.9638029+08:00","gmt_modified":"2026-07-23T01:37:11.323825+08:00","raw_data":"WikiEncrypted:XMvsRjFEcSrjMOAT9RAdm9O4LIaLRHUOAniVL3dWNBSJQxQj4YXH0UU/TXCEvEc2is24uTAghqduv12XZnT3w2IihMS5TLONyubLO2XL+NM1eHSayK1LywMM8Xr5TxbHoVFDpod9ccm7pW6dn2c/TviJFkYcIwdnrFmBwszk75ubjYC5ONqM1LzW+lsUF7331+3EBv7eyYHd+EZqcV9JW5QC0AEFynNVF1X/3Ey/BK3qDchdTMGWLNrGuKpbrxwbsvdROl+Uw31tnu+tQupRlt74nmAHXXLjETl7+xqi46oASNEA3831G3rieTu6RYhJ4lslgy++bWDs4YRBwWTZzZeQWH0V8vcjAvZvYLp88661iTTRWui7YhdnLtOCJMFXeUZyKWzx/g/vzbm8l5QzIewzqak1k37DygpICk/jfwp3G0Ltq8P+RlaOKBpQ7N5Tf2HcHg5HFFYVG3xeZgoGbmkQOuOohUp/5MF2v6xnJs0NKi0FxqQHAP2qc7+3R88hLgOI1N4avg/qq/ebTE/v77aRIdoUB7I6mW0WM/NSX0pf+xc4BWvEn9kgKdCOyrFXZsiRDsopqRSsMECR5lDyJ9GV9TeA0e8G4jVp9yduFzAzG96VsRDp6fkoDgJDUJmbNmTwjROmSoYNjU6qp+XMnpESqQIWaveopMXQBlZej9Qt3Rl7SfG8G3HBooyzGE4QvUMFJzRn7zVTrfGzajuTm1qzOsiruFVDvuNLKritDnm0z6UT9PHk3SoBsnacMFwfP4Gah3zy8YcbD1hGSZViN9Ke4/MoEim8wGKcn56tGyY9JnAU6EMQ6l7iD5F0v5mkCu2DiyLPWslsJcj60x826zpfwuK+39hsyOd2kmcR7ZQHgZ6lTr/gwwqdbkzJhfntukB2V8HO+Nx2VmCr4V3iFAJbfkq86MaczygScQarHGfIzI2GGjGg66DOacWfV4ox","layer_level":2},{"id":"061f0c40-a29d-44db-b39c-0a6dde56f826","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Display Components","description":"display-components","prompt":"Create comprehensive documentation for display components that render data and provide interactive interfaces in ApplyGuard PH. Document ResultView for displaying analysis results, Tracker for job application management, OffersPage for offer comparison, and MockInterviewPage for interview preparation. Explain data presentation patterns, chart visualization, table rendering, and interactive features. Include examples of data binding, filtering and sorting capabilities, responsive layouts, and performance optimization for large datasets. Document how these components consume data from business logic layers and handle user interactions.","parent_id":"4e6884c3-ec96-4738-b40c-ddece5a2a3a8","order":2,"progress_status":"completed","dependent_files":"src/components/ResultView.jsx,src/components/Tracker.jsx,src/components/OffersPage.jsx,src/components/MockInterviewPage.jsx","gmt_create":"2026-07-23T01:22:13.6910331+08:00","gmt_modified":"2026-07-23T01:37:22.2959249+08:00","raw_data":"WikiEncrypted:fyg+ilga+Zcl367hKwfwxZnphcYkSZ9Z7CV08CzRGyD4llY088Ux/NSUgotBaaF9o8UO5hkXRbQL2vxY7F7YE+XbugHOo/usmm3BwLuK9DN/UGjgfGqavv7FWXCWeRjA8jx93ThYRxOp/NYxezVwQnZg9lNQq4xZfT7g4CdzRnuzcWjFNrDYkw39i5QN3AnO2iy+2qD9IjlXQTcU3OOHNVuToJd56vA1dysx8KjRbMmjZ3XGD2L1l6SNuk6OEGKPek6qR5mMKAyxFSU9WV/DZ1TyLvOp2mYTMu6f56c6g0nWUawqMvjWM6mkNEcS7aJAyOIqpZBTPGwRw+TEBKXE5lyrbmZ4P0yAWyi1d2VEFjtj6xW/EvTpPl1BW/y1Xlf1oGJfwzyokbbh4mj4OyXcGCdkZS+WweYaXx2Ia3stEWs9SDrpmLFksmTj+bXNUybYxJBZ+/e+r98xDFFF44j/qMVraNErkTnv4GZvOLzzbKhlhH29QJR7aGwFYS6KLfzRDkVzSKu/S/+4IjKUGuDHS6rdc1mgpu7PixX3Q1wmfhnSqABg1UThxWgFgBsc3ljE7mBScUaEqQePIRR/Mrd1fs5LZpTiygU4Z6mFTxr+uvNZGpYgBIkw7hwPNokut7aFxUQBtbIbLCgDkGjH/Y64ICGBTXiG/+tvOmmul5FV65h2OYLM363QUsPn3NKwy3QhSv4Yvs65H1caNqsjdN/SSoZcj5UFlfxNmhP/ZCjRvCpvUNhW4Wnk42mVWgxdxpcgewJioix5RDLGBbS4JOK8HnbCWZ7NkotIiRd0YlS1FWck73Knty/VQPzabcF+n1FRY5f4dEVXhrhGNmAmOVdvDCylopKWwNu8w9EJa6fDFDDjLex4B3DcdAuT6kAuWRlba/cobkbaQzIsysAyKtEoVDc7gyvVFBKkNKAnnn77BtVismcgXU9Qac76bWWStq5NO6i/qPq6RY/6vW/6/gR6bBbxIcjFVblpA0MBzivJ1be9JFWd4hqrz8F8RK3c0bSSPQ5DEU67i2jdm0Xl4GXX1POh680gciS/80lngHbOaZnLxLouj6blJHhd94yEOY4jSScxQn+JO4th2GJZKO5nDaDzpEkx6erBJhbD/LYI0WImNlQtH5UoCQBIOPK7fIRhi9iDOjccQtThsNkqNG+CCmlX/WRdCfLURJkUAEb9YRZS5eUHDE20mXKMy/WGFixucXv0onw/zZBeym5pOzLMzfFe7cdSJDm2JJp3mX931QnvhCeAguXLW3hBMfAZhXfcILY0YBqzY/41S5H0YoG9487we3W/b+NBvwyhTV0Zf3pq/6rWLbvsfdGNhRtJ2Hg41rXmWHwdu89ThgSDENBD5T/7igZ9FPKbhRPWfTOmSdi/vM2JaMfL51CRr6L6bD6+lT5BCoXKSuiO4j8whUxswi2SI9QAYltzAqbH6gCJZKDRPeY6FTUg8JYW1VFggB6oMzVR9Lx8mtmhLkkqM05jCFbL14VrM+vg6tvwMrCbWMLdGTKT83W7zx4yc7na9/B/10s0XyABd/DbuQrqNNjxvwOPrhS90ksu1IhCdteB80s=","layer_level":2},{"id":"81dcf3b6-f857-40eb-b45d-b90b9d19d001","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Build \u0026 Development Configuration","description":"build-configuration","prompt":"Create detailed documentation for the build system and development configuration. Document Vite configuration options, asset optimization settings, and development workflow setup. Explain Capacitor mobile app configuration, deployment configurations for Netlify and Vercel, and environment variable management. Include build scripts, dependency management, and development best practices. Address performance optimizations and debugging techniques.","parent_id":"bea14602-7013-4ae9-a2ec-8f0c2eb62a02","order":2,"progress_status":"completed","dependent_files":"vite.config.js,package.json,capacitor.config.ts,netlify.toml,vercel.json","gmt_create":"2026-07-23T01:22:19.1405359+08:00","gmt_modified":"2026-07-23T01:37:17.291047+08:00","raw_data":"WikiEncrypted:ZHd6gDb1oAMJeik+Vv5fPivWWxPOpIXhoUfW7J05QiKkOk1Dxj1c96uYIbj0kiTpsMd4H3B6CWM1I+Gm1nft43c/C1HE8ek7YxZzZg2jHvZeutRIQM+fNs9P2n7G9ZyYjW6o4I4+xUNIWAcSvsWBaB5Z+P6c3Ak2z6Ex9ACfuGum/paCdxGg1HqN4RAvEMnYSgGpe+5vI8cfdEUG5PxsAwcvFnBjrZhBJPOKAGx3J4UKNuCTwTGbh/oNOfvGfqowgiRjxJkymYbskMC1klBE4LzEE7YHKTH+Af+kHDM+VZGXdGlIpfce5BlYv3pha4+ciNVJqltO+Cm+buGZhQ48USV8HXtrHiyXzfpfcHsuocU+R/kBgT7LsjGlfC0yX9cEdbFssxyUSxr/v0I6snkPTo8OTxoxl70EUByQf5AVTIDm1srYuM+wWumyB0x50wXQyC5PypQsNrG4UfBjCE4WvTYdMCrOzPZ0FLOdKRzKDG8Tgkprye5etQ72xkdTvpN+iteKsgNN9wM0t9SgPafK08gI2PfBFt+2r9nJdMPiy2Ne3Oj+uBXHSdEOxK602SnutBDHshLzWAly8Bx5lhgG9beMPAGK+IMkn5bDLhvEDNSEEy4Jy90zsJuqUEwk/e5QpbKWX6JllcJVlu7/ACR7/hyNDR3fwrvogJEqdkV9B0pDGAwUXK0fqwC/w85uHyqi0RMQqS0irhQt+/J3gi/OHaM1ea/14EDzblG88bvCEDaNDnhBDM5ShX9NbFsJ3fjO7C0VG2y+DwQlI/ltHoFbTMH8UzA/AquVdeFGiNRaosnuRhaOx8xXPAWHb7jvN3ONNP6RFfcSXF1jVoOGJEv3my5Flk4SIYloDm0UmSm2mcq0iL0tgY1z9h5mSxw+Gg5VeJcYl597FEMjzuB5ghUTadjdTPT5TvID8mMEi307XpBVw9fHRxC1NOUahnSF8akOa/f8ybRyHJlLzW21iHKyUL/SOIgdf5qFhDvNOLoyWNFy3dru4fmmzHHWfNU8VDjdJ63uMDGlmhxR9K9OZsMSfjkH1JB6lAkIoOHDT7N2MqsCt/y0TUohN0j+a4fID2mHsWBMGzB0V0IP05a/+UuPppkguiSvr+koynBZBOFa5Vp7EtbpZLHOU9qTT7NtgXO+MS/8puHHjn6l2BysKCv8lg==","layer_level":2},{"id":"bc2818a6-4a53-451f-9518-11a7d1a1685c","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Database Schema \u0026 Migrations","description":"database-schema","prompt":"Create comprehensive data model documentation for the database schema design. Detail entity relationships, table structures, field definitions, and data types used throughout the application. Document primary/foreign key relationships, indexing strategies, and constraint definitions. Explain the migration system workflow, version control approach, and rollback procedures. Include database configuration settings, security policies, and performance optimization techniques. Provide schema diagrams and sample queries demonstrating common data access patterns.","parent_id":"b9cbb862-07a3-4429-bb2b-1691865594e0","order":2,"progress_status":"completed","dependent_files":"supabase/migrations/001_schema.sql,supabase/migrations/002_paypal_fulfillment.sql,supabase/config.toml","gmt_create":"2026-07-23T01:22:22.8311242+08:00","gmt_modified":"2026-07-23T01:37:48.5555501+08:00","raw_data":"WikiEncrypted:veTYwq2y4io5qXerCTrkkKY19u2QVJ1rg3+MIy4jIV2G7991jW6cwRmNYXwYpuW5h2rQvnmqJPTH46LFSKvPqWVwMVGsjossRk4vvK8h+Ms5htMkamtPVd4pC1gcrvVmB1Bix8WrXGfMg8A4jHwhrudRRY0JwTgC5vsN2c8v7nZ+RFXHa1AcWr2ZFWSZfN39ihPgLTTbaDjp/UtE2B0njFBT+GLPTdhEFRcWgHHTjkDRbS0vbkCP86zWlAu/zk4g/KFq/ZbNnRg1ETauoF7uvmvjOBa1s4SCe6BmEPlASI2vWSX4An5ouqU39aOATUSEpiBHeiBPM/uJdP/yf/On/RFVSe5oTvqoLe49qLwn1GlICvoLZPjuZqjiqhJmVo4Hd49Yhn9Jut6y5mWNOYySaEFBZiXMlks3D0TwEFMWr4GNsT36pJ/LL+yfeUbkNxB+N2/cZazxcz94AVaBs7b/T4OYsgZLQ0cbdfRGWkPTHXL9SHR8EV5erIcRNwSavnoBfz+hgL6fCy8n1jcPL4UsZB59c99oN4Mtb8EPf82EpBAIiwnwhhZ8CAUj0+mEfUmayTg2pobEAxKVMpUjdd5n88rF62SYxQCeETfgGkj5r5CWMR9Ztjty3iQRc6+VHKmZ828ysbwSJ5yLA4gGT7re5pH9xzWuo7WPU/0IRkzqMWvmsWXWyf4mG2+z8RoYGa/Fi2zZztMzIRgDT+UPZCy4RTpVI9RuQcaDmpDRAXc1Jp51P7vTGd07Zet8zB8Y7GOxco0951WYo5V3QzBsId3BIk0OXNMB4uoJ9Vx1MxtY3wGXojaYWdkB6LCEGO5Iy3DCHNSdx+mGt5HhIzpV9nV4qkgxrcT3qhojvb+RqCKMJDceU7m9pWUjshgkEVKlC1TYN/v+eFHUaPCJHsnvM1MJeaMkyx4xqrfDH8RxciQj618uw7OGqF3MDNaB7z0VazZy0vOPFoN8nR5rMWHrQzy/ygxY3PdbDNnsUjkXt1O7myaBCYUdEARgOoOfTnfuCpPYDmItw6lmzvOBGINDVhbC4JUMYoO60QljMFwNCq/CIxxCZECSCi0q9b1+aJmHm2h2/669ZvBGNHhdfNmqAeRymMmIV95W5BjiuwpD2VM8odoKh+FBOcOOnKiKpNRZuktZkxcUJMMOT2hoiuPYFwve6lHRhToABqbbpINpt1GxSSMbcFWPovDBFHfTQ6lWTo1KgY06fSoql+YmimAv0R/KBtyaLWp8cTCBtwQ3nG0joMHgh0M9gqJVWuV9X9hlskxXZesqty1AAUtgVgSzUqWROuxbppJX2y9so7QcDJzVKRI=","layer_level":2},{"id":"8e09b78d-e5b2-453d-8bbb-2e3cfafb2f05","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Content Parsing Engine","description":"content-parsing-engine","prompt":"Create comprehensive documentation for the content parsing engine in ApplyGuard PH. Document how the system extracts structured information from unstructured resume text, including skills identification, experience timeline parsing, education extraction, and achievement quantification. Explain the regex patterns, NLP techniques, and heuristic algorithms used for content recognition. Include examples of input formats, parsing rules, and output data structures. Detail the validation processes, error handling for malformed resumes, and support for different resume formats and layouts.","parent_id":"6dc96b36-07c7-4466-bd10-1f0ab817577a","order":2,"progress_status":"completed","dependent_files":"src/lib/analyze.js","gmt_create":"2026-07-23T01:22:26.1371574+08:00","gmt_modified":"2026-07-23T01:37:49.2981804+08:00","raw_data":"WikiEncrypted:y7hjn2ShdVj88YDbsO7CF422YnGwZCs0u1+mf2jgZ1bSSXlXlPBFvfmmYD91ySJc9CouDcaaLFxnHit4BRCbjqpCgRsBhonrUYhP/THrZPv9pMN8uo9u9R6Kif5CtNmmweR6G8S0Q+r5AYie/nQvVqpD+MIkfsZjKKvEzATrBCcIWu0XLsY8PB8xEw7EnZMANrITz9QOt5TTm/oj16mOJoW9FHsxq1+QJStfajs88Mn78rNbxBrMzJLXEJrA9dRXuySbFqA3x42Hm4hjrcYjaXi58mVS2dpO5h5oWF54z4GUEDFjHH/JQs4txnWeN+z8kDBYTTkquOF6cmJELSw2kbZzUlAMZA8M6MM3UM/rhLrH1HX/t0D/jdboxCI00FIBRDxYRPsk6hF2ZtKxTjA8aOnezzDLVB2hqP+GIlbh2I9qoq0xm0cUUSd+K6TBHCTqdKXvR5qyAAn4MzYXZ5U/x/xMSQWgw/I/P7Cye7ZSZnfVxSN1lt2PlCVXQcwsnUVfgVTkkH6RtOAulJgh4cpFFsZMQE4pvs5XpSEjf5NRHNVOymf7EnGyyQRxPXPTzfjVkfWoYts8IWiPZtN6cAwvlBsTeEEFRyW/nBIcsSi7wJpxWESQjXkC2/tLnRKjaVCHLaESJc7Zes310NbHYqHoN2UxGMxCBdxaAX9gKvSzgT0GcHoOSq0AyITSADi/4dftVHxL9Blad/O8jVucsXTU2VGtG7tYfRwRptaZuRfFCUSTzt+bUjwIDeVD6r3NpILa7PBmo38LnrshU/icLZEPlYoZXHYr/kaUCHH8CxaY8DyVVcVmSx2K0jfrQJKWBK4T+2rkNjMpyi97I/Kw6/c1LiYKp+eodr2sxqyFEcVY+0waOakeugipt0G3oC/Du6ykZL7Xh0v6YlAx+imvk8Uq5i+3POUkmkRmsgx13YR67sKmMZIPnSdAL0WxBIV1i52DYyxGXqpftcL9SDAmCjcCkgJH1xGyL+PZjFBVeJPQEeDBTByfGSWDfHtTEmMemZPClNtaUspNA+sq6FD3RXxAYigb28ZZQmvixr4+THKec7MXAleqo2099GMdsinsDfyY5Pj5hRFRVaV0yV5KL6eNpeNeGLKP9gVHuKm2YYptJvDmIMgMvZfdoz8/SWuZYIsp42EyFD9/pl5dZJ8oVWfv/xYpr40w43US/MOIXp6iyXSFD6ORirvsmPrvMfDxshDXo3AAq9yiCBzUm5EapBA582QKed9eg2Px+nH8PNCO19cByZocUEjdPy6ssc302u31rFx6cWcbiPRzCYa6ZdWF0rhbi364Ur1IrjGrfLW+YG4=","layer_level":2},{"id":"cfd994ce-2142-4648-a724-dac2936a10a9","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Integration Functions","description":"paypal-integration","prompt":"Create detailed documentation for PayPal-specific integration functions. Document the create PayPal order function for initiating transactions, capture order function for completing payments, and webhook handler for processing PayPal events. Explain OAuth authentication flow, order management lifecycle, webhook event types, and payload validation. Include examples of creating orders from the frontend, capturing successful payments, and handling webhook events like payment completion, refunds, and disputes. Document security measures including webhook signature verification and order state reconciliation.","parent_id":"45127b67-19f5-42b0-b44e-63fd3d377aae","order":2,"progress_status":"completed","dependent_files":"supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts,supabase/functions/paypal-webhook/index.ts","gmt_create":"2026-07-23T01:22:31.9828256+08:00","gmt_modified":"2026-07-23T01:38:06.8844968+08:00","raw_data":"WikiEncrypted:lwC7d6wvFUcTMCQxUtXdXkYNNOFynXERqYUdndA1mguvar48O/GwK6S/6BRtPMRgWSqVNzstBJTvdfAU+zik2U6lIiMkbPu76rT342OkytJyuInMCkQXvk4UvxPuhnOKqa9LvOZIGzolOSr39eoJzfWuVlupjb1wBdDj1lJxTCR1TNecWxD6k0wcD+R9Umpa5qYqvMLnIA7kdeSSa6SXNbMt1L/T0ZjW6GU/i7K8bxHCM7A0plspOHuDWcI7or/gY8Reon5toD0olSHS9XsQ6cT7TVYVdBdDk2whvfpmAQEKZWcpOURN6qSWV0IYAaYR6wIuGTQmCSa0VGZZGiDM0JaadWo5vd8+vwe1nbacqRjzKwXBSwIcD1Zbhji/2wBB8gbZU84/plG6GIHRHsOxGNYYkEmZaTvGVblGnQALre2troVcCP+0+UObe8qtnBQwJ+o0S0vS0hHB34XmGKwwhDZjM1xpKhV5IQHbOdDIVnxh9jmk3cibcw3cFCMFUjBbN7vTEyAJka3s2Gb7dGEn3U2P87okdWXE9rA4BhgIw6P5tJO1dRon9gZjc34Mcs9MLdYfU8JCMS+U6CaPmADO1i6GyzAtRrIzc46MrQQeHHc6sQ0rs83DA0BW4zRNljxaihkpW6ajaqpt70EnaHDdub0ijLt713L7WUlPQ1sry4irl3C5aY6T1X4E0wKXI7l65xrCfW/nV+QjoHqAd6CcT+Atnrw9s9BIywLNFBo8anrHCjghmkG27oS8wjfM9LE7w0x8pCawCHX4IsjRJnbozhwchK3diQ+lzLxQ6YW8l02WJdKa84mxpBTpfk4Rw0hUwEZKAUlHbQXPXDVsSg89PDxvUGhOhoGx/qnbATU6aDuY9PwKxFkJrds9vz4Fk3QlGNgZiRdyrIIH78JnpdhFMah9s7q/huxXOzHZwj6DtPv2wr4oQAK9XbqToHP1BlDtFb2GKCFAaLc0wWY6XfMwpPr+yRAZBXkYTGfbu/v2qrw9cJxTnwidxd3FsAOphHKDIyaZQMRlGIjdBzW7pY96TWOhXD1t4XKPnuw8pmG+v5jmq2mPi1XH2yq2rH/il9kb40Unvq62pdePiHmq3eKBtsyton3ZfTeBVyvxjXQOCe2Ale44FYGbtIyE2EprUexHUA5RzFJSAW8/8RLv3TZzdrxD4Vc9Wb6Z7kt5l6RXSK6+VyenqVwRGOLot9P5uN5bGwxvfidzE+o80UCrMQwuMUe30koECeTdmg3IFNHfVhslT9VH25c6yecOoip8T/jUtAzC4pXNHWaknkMsl2ljZaCo4yK+V7ocpr97iCzg8J8XOA+lV3Cd4S3qvo4DyolLAFgX8v/49X/KIiGembuKm+DiEXiWr01ncoAQI6/BBMg=","layer_level":2},{"id":"bc5a4e4d-5060-4d74-8601-25ec04432b1d","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Data Export \u0026 Utilities","description":"data-export-functions","prompt":"Create detailed API documentation for data export and utility Edge Functions. Document the message pack download function including file generation, compression, and secure download handling. Specify HTTP methods, URL patterns, authentication requirements, and response formats. Include data serialization patterns, file size limitations, and performance considerations for large datasets. Provide client implementation examples showing how to trigger exports, handle download progress, and manage file storage. Document the shared HTTP utilities library, request/response helpers, and common patterns used across edge functions.","parent_id":"aad58f1e-81da-47d2-9000-d1e4cd8b660e","order":2,"progress_status":"completed","dependent_files":"supabase/functions/download-message-pack/index.ts,supabase/functions/_shared/http.ts","gmt_create":"2026-07-23T01:22:41.5474245+08:00","gmt_modified":"2026-07-23T01:38:24.6705273+08:00","raw_data":"WikiEncrypted:tJ25FWc3qLS7BXDXgna8sJalyZzXVr784trQbJLCKvpswHvEqmQhHcUVJPFeN3AyFlrjbOAphgYTFyuWsawvtho/whh6npg1M1eNtQJLR6PzDfiCkGAOXsXl7vtQllIiESJbcfYMW75g5+zA43jOegg9Fa0OvrcVJ1MTvVMAJhscmW1s8nhzc6UNI/h5VNTnAjfbuQ2PQCJnwmrn5+RG3JlWgsJGyMD6ZeJPVgSit6Q/B56enTCqZL6HcQJZcr8vboK35rvsQ9VnXlZ7Cx94f+g+CvpopUfaZndlWvSJ/LuPp9Ep/l86ainewMvN4sGxnOZMHcw6jmJhybZ5Z3efTLnonjtzL8q/98O1CgQgZbSivTfahvneOjXMU/tSpeilAMWuVTJHQQFKRb9TJvIihkrxudbc/hOOIU92Je9CVnT3ZvIKfasbVLIDkHbN9AAVLf5q/zW5JZDCCj5KRX7vKaSIrCr9/XZdxXMyI5rxnPeyFJiZ3rCNm9o2wU0RD4dXVJp9uwhyiBohxAgbcxijvg1htarVmGuriMsubUAkndAum3pDYUlLj/hYr4z9GZ4LlIc9bTWDNYICCh0ofgdrI7LwXGOk9YWeGhLKzmCYC57MlSLSnswlfTDMAdK3laahZR25mLTHxANeBmQ1iA39B3ygECi6FvfKsC7OvzQgweD3HSX8pb0E5AErAyJA/ISyVWkzk5YaYGnZ6CKmZCkS3O7cqf4HbdaRu9p5fqXfIcgGfLJ45GmheP/F9NEpBkoeg3FtXETpbYTlwXDLXiRCv1yAZhkfgkH3nN7U7WDaKqNXWMeSfnuEkWZAuZqBhvATTqoIBHVCmqyrP3zM9OPKBMDLCWdj/EhQzAjIHT8GVIbImwx4H9UeBN/7QxpaMsfg0zfwuGUD76UqsdyTs2v7dTb6Fof4w4fW1+1XO/xThS7skpEe2Itf0zrAlSeYmEsXPmiwiav7R70wYjTZKL0yf8br+XhX5rZBebNlB2Y7wneZF9MbGe38M5u+q2a5A6iI7JDgpWWqtpYUVwEjAZPfGa1dptv+rjJD7Pxn0c/EVtYF/lbp4KQ3XQju2OiFWjwHE5p4LyJrh36Cqr+Np99RR4lYKnKFWcHFOc0/VX3plh8Y3zGLUp4oRFwtOWso4wc5dTmogsVKmjmACBD7DkCKR1b53M0HIPHTQml3m9CTC7JgxqaqHLJxMdScrwkDgqNEg83EmN9aDiq8pf9vez0ZjwP3zHVDXo/2onxL6xP3mR7wU+vz5FhN0YpsRuVn1K/TI/4Nf2WEbcfSKw4UfYWFyVWqbDrEnSSqX9NsQdjJXCrKsXrM+LlmfuGSiB2/VnImtp7BcPy+oU3k79+5hdD5KKafg1RKXgBZ2olD3PUmPtZ/uvc6Y7f0Ok/APM/Q4AIzMF9QaF7+wF4cuIWyTNzahg==","layer_level":2},{"id":"4fb1906e-2fd3-44f3-b2fb-85a358f4eb2e","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Display Components","description":"display-components","prompt":"Create detailed documentation for display and presentation components, focusing on the ResultView component. Document data visualization patterns, result rendering strategies, and dynamic content display. Explain how components handle different data states, loading indicators, and error presentations. Include prop interfaces for data binding, formatting options, and interactive features.","parent_id":"80cd19aa-ad84-4b1b-b83a-8a34a7c03774","order":2,"progress_status":"completed","dependent_files":"src/components/ResultView.jsx","gmt_create":"2026-07-23T01:22:42.738593+08:00","gmt_modified":"2026-07-23T01:42:03.9587481+08:00","raw_data":"WikiEncrypted:fyg+ilga+Zcl367hKwfwxZnphcYkSZ9Z7CV08CzRGyD4llY088Ux/NSUgotBaaF9o8UO5hkXRbQL2vxY7F7YE+XbugHOo/usmm3BwLuK9DN/UGjgfGqavv7FWXCWeRjAbBtasDk56eYAMG/geZoHDoW6xUP3xfhHZ/RzdxmYivrZsM+VAi6+f90smAciUQ7ZTThw80K+4UG4worZ7rttUlbcepv/nSpFjS7snEpAH15EQuuftUpSeLUTYDYm2b3eNr/DQKq7WYkvCX954i512P4PHB3/GOpUnj8uHtiBrjVggBPW4pgY8mB9NqmTbmByHXNBn6taVPFDvwf8u9NTmRoRhgLZA/0ADw4eHd/NJrUpCTLKuzcHmvgLiikgUUHVxsUEFn3WAqrjozaNr8xRCn4n5+Uz7Febit7u8KpWqZo749gjsji31GQi2B/qM0JlNRQvMtHEqDwzbwlh1uO0vatszJSlaLj0yWiaaVQ5HLip2oagOM/DE6LOQR30aRc9oylWrD1ZetNz+TXY5GDs9CKH05aRN9ZvPCyAEq1YCD0Q6byKS2KoveIJqTMqc7/pm2HRntP0qumnRi5F//x1KnhamGOaBd9vfYiVsu6+/RFlJ3Whgbprx8/ZncKRGuX/2YIbwN83FntVpiNoUeN8umT6CAF+QiRTUmGbhIFKso7nMAxOWpWwdJ902SepQtP54H9Q/VCxHkc+mgFyHnVOvqtrgvcgs7SVBnVScEc7PJgaJK9zyQf1wMQdZXQla69aFUU4SGI8TYa9MX//zCe/qPLyJo/+tVrzyR46PE9RIsilRk/rpUwBT94BHzJzevcNL6m5vdszfFHVF4GVoVqNm5sNAqtFxA2DM7VuOz+9cXPQDeFyIMJ+Xlsee3b8nfhKCvjyDUT9x7t+SrywLJcocJGOM+ZknVj7NHsYEsFTEJb3sePrNJXm0wTkoeu73k3mJTKV70Uxr+9ibM2xmo3ox/6/dgpjFSDY1atODSY5Ppw=","layer_level":3},{"id":"0e0ca600-90d3-470e-af91-b0e36e3544e1","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Checkout \u0026 Subscription Management","description":"checkout-functions","prompt":"Create detailed documentation for checkout creation and subscription management functions. Document the checkout flow from session creation to payment completion, including pricing calculations, discount application, and user entitlement updates. Detail subscription cancellation workflows, refund processing, and account state transitions. Include examples of checkout session parameters, subscription tier management, and error handling for payment failures.","parent_id":"ae6aa76c-b442-42b8-8ca1-b2688bab85b8","order":2,"progress_status":"completed","dependent_files":"supabase/functions/create-checkout/index.ts,supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:22:46.6355097+08:00","gmt_modified":"2026-07-23T01:41:56.553243+08:00","raw_data":"WikiEncrypted:/3r/IgJF/D+DnPujiCpodlcVnt7P8yexE1SU6erPEyXNO8T/ggFw5cC6igOgWud76uGDUqc9B2NJ88L4al5OaWQ1PlfEz3Lr2pP5pAj+iIUmLnReYeU6FNQxR9/fN/lAYyCmrhg7k25NDOKJ8bMoRCQRl4MHoshCvj7vwuKAAxm+31hc1g6PtoXSgqdaGzKifArVVO903UJF26TXiQBBiFTAiekCgwJ8rn8vppaa7PIvLhvVlgUCBupe8b7ELUq+GfZLM9rAf9SdIpGUm7ISn958V2ztJa/ckT7TMe2PdqiHuZn8gcr8XRev1Vti36RVBOtl6DmF6hxQsfVGRXBtPslqbR0apIULEJKF2E6g1Kl+YRL02wyo0cRgAfnsyaKAq4qLDDqZYcE2+1UGadP5TdpZHlPTyhWHYRen8T2lafMie9t8X707/9dnSULl6K6PEVUBMeaz5Oat4e80jmgSgIWOPkIqQjBpn/8yendY6Uw8nRrRVy0hQA6QntJMUv9YYx0uD7sav8leyLivqNEQ4C03gH0ey4Am47J+ZMNa+JXntUE2c5NZXTtqzihUVA/4iC7PIgR0VkdkfIUXbk6mjMhOTKURyQaeJLUgGUuAbz2z8+lWPFPOsMQrTmcfq8jqGsX9fLoINVu/efPXo3ivWgjIytvHIGfRURh+fRS7MEWtmUbg2pqIX+D8NMTLHLnYm4wamEMBnRw8yGmafND2qC+PHA4Vdof1NZuz+u9stC+vWhA0UYEEpf0ps1WIEEHJ9w0vbmMigXB5BiwBS9oey4/1xX4HwWvkxpT4IH4uw2VFdUg2xc1aqd8qI3VP2COA/JqV/H84boiMq3nDbHfScIO84Bfd4ULvJSjfNWdKlc8poAp/XmJDbvs0/3FLbz89lW3fMbgJflWg6QoR4awPHe1FZjIc3kJVcQhCjEO+5Zl6UZrxc42/oR01t4CIiCWsEitGIMFUsJfkZAls0+w5z31+eYEhu6z31ImURNU8WGfTsnhWwHG73olgYER2vSujJCkl0GMvu3+/2TtNcRFIQeFhXiBUnxZveTiCssLovAcGJ7oTb8AZYxyiQz6yr6nEirHOu8xEAiabgq3lGdQRCz+Y6RZV35ql2QrtLi101AysAGaaVZo7Qql9LrntpBfD5MuImkrUwYfo4PYQDDsUi9BUtVCAWhkwFzEbFN2DJkjXMX6Zb2IdEdaPsnQqE70c","layer_level":3},{"id":"77d36a58-c65c-4218-b574-7b86b031d000","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Order Management","description":"paypal-order-functions","prompt":"Create detailed documentation for PayPal order management functions covering both order creation and capture processes. Document the create-order endpoint with request parameters for subscription details, pricing, and customer information. Specify the capture-order endpoint for finalizing payments and updating subscription status. Include complete workflow examples from order initiation to payment completion. Document error handling for declined payments, insufficient funds, and network timeouts. Provide integration examples showing proper error handling, retry logic, and state synchronization between PayPal and application databases.","parent_id":"8c623eb0-3465-412a-9717-f8413bae5ca2","order":2,"progress_status":"completed","dependent_files":"supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts","gmt_create":"2026-07-23T01:22:50.2757272+08:00","gmt_modified":"2026-07-23T01:42:31.1965376+08:00","raw_data":"WikiEncrypted:lwC7d6wvFUcTMCQxUtXdXh0n788usqQBo5m4BifiqZP/7qcEgEdY86Qzzza4ZQtMZD0CYY3crNO1vM68DD1j3QvSU5iZ/CrTtfyzbO/7qqAzDTodxGvfcw9G1OjWRph/aH6SUodqoOuQx68Ekpi4Hs5Ir6WE+pk6NsH9elF4/Frx7oAB7Q6JU9a2fbvbS2SWo0+wIU6iF6qtucqeb3jyh9dBE7iivIupIT/XmA1QcSdBYHDdjyTd0unm5IBXEgY6yWcnyoz8kfyVXlosZFuZveWtSWyFqm9dO+YTN/kP+aGrD+rcyS3hNykB3gT6vhYZftin+Ghnck/3hFtVo87LYdHQX5h14+V0qmxoyTV56wdc6XO83xEx004ZAfCfe/WmVX+g9iO/cxbWuXZ2t/cKcmp+FJl8GX2yMm1GcpBtRHp6wgHJj7yZX0531aBszu9qBGA5XCNaE/ShezIg35tpG48xKkNiyUF9kGdxKSvjUEeJm5y1dBe9q3h9KVH/WmberLsKPyiubEhBnP/bIlV6u1RYXTmHsmD+XtiQPUVCd/E3YNmqSLvlWhh0hifhHj0HjSVzvF9ie4WhM5Ojg4B/O1ywEAV6Ih5DXRiVRXe5KHCFI8EA3Ex2QkxFRApzrT4eh2JNpvuPFM3Z4atydXNkwcg7P/YxvaXqLUoRbncUkRZAYmCTCHyxO8HIHiIm8KbqW9OSQB1LnbfJLcbVWvYICkANc+0QqIAcuyTFfVZc69QSA7ODwylvCX9nLHaOo6uaDKSmBVnoDYkncyti6Xz4j+RaQlHm4fHF9g9vP/Q0tjHYZavkZi3KflJhZPGeU+BooSmkhITqfyHKf9ptXOxM2KOtzJ7rbSmYp2kiMw8UTnYxvWdPd+2QJyYT4bBmhlEmRSl+tLn6QICVacoHMWbyOkOh3pAa0qL76CPaXhVfSioSPa/auIn3WIf8UMibFSd98qgd6pvNpJ+QwIsTFl7SZ337bB9AlO5iF1b3v8f7Z0p+5YH/de+k85etmdKBQDTpUZjCIvdg4D/N4HwmuIbRbrMA699dD/bPP+BLF+NGMGZUH4HnTFTFOPUUHv8e+ln/rlVmPUCmsnOg4fxO00Zi/Y0L3Q8zDcrZaDWMLIgWCH4N370LDXaTPRpqyC+vqWmpDvQIkYOOCTEsF2ndmXomjhE0FAyUvYjT0JcUBMbGS/fja7YoXWdi7toLv3MCpkwK0F9mO1mEgAEQzK0EATrE+SLmT4OuVAzefH2mVCzUs/fw93iDTxOgPvmbllq9uEbuSxNJZvqex2/uZyj2N5VoJebSb6Wveh2RPSnqrZKJis96EoxO4o3RAB480ffPlQ2AI9e0kyKSfmxZ3NVvvLHMACOmor2x+OciCjhqMgkJXN5RVSG2QhItoaPzBxJRG67UgHtvx3/gyb9Z+KoAfzM0/1C1ycpc0HnCZnMedvRswos=","layer_level":3},{"id":"a74e4570-cae3-46a7-b9c5-bfd9be09e8fb","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Order Capture Flow","description":"paypal-order-capture","prompt":"Create detailed documentation for the PayPal order capture workflow covering both order creation and capture processes. Document the complete payment flow from order initiation to final capture, including API calls to PayPal, state management, and error recovery. Include examples of order creation requests, capture confirmations, and refund handling. Address transaction security, amount validation, and failure scenarios with appropriate user feedback.","parent_id":"672fcca8-aa26-4601-b5cb-90009d3ba4a5","order":2,"progress_status":"completed","dependent_files":"supabase/functions/capture-paypal-order/index.ts,supabase/functions/create-paypal-order/index.ts","gmt_create":"2026-07-23T01:22:57.4374371+08:00","gmt_modified":"2026-07-23T01:44:08.1478597+08:00","raw_data":"WikiEncrypted:lwC7d6wvFUcTMCQxUtXdXpM61qczLCMK0+jKo5VPc8M2ROwnBxX4ZS6lsbRezf/oAtvPN5etQdUT2KcMUNLmonQxx0bkX0hZVrNmSDf/3ALi21qQLMno+QNLFTQRg3gij9VDc2U8ZtXWw4J+EVnZh03kullS7JO/BrQWyd0eqfbm8D7lWYayOXZ7kgc5Br/6dd33BTA1IBKPduOU0j3fJMC/ywCq48OKGNEIynhWUnpUhU7+LGr6APuqg0lJ7NwsAmdVZtSzP1YFUSPd4YxU4/kw6RPi7hUk5Q69wuYH73/gYz/r45nkqm0ruVeJGR0HuizJM0dPwZnZbWR1mUSP8KM6eQ1eAg4TCFg3IOVJ9CaGdB/FvTXcf3LrqcGv0bPqRuiig6MNZs5moFD7XaHSj0pMO6dgmYQqe9RLg91EdzUGnER5fMJdRhH0qwQxDhkYPxnAkBqeZErsCiyp4CGpfkS+UDP6eHTRNdK6081EUVzqpn4MPbicJkrq4gLBHwGO06Q9zP3tWUzK7lFU23Y/AmQe3LCmRgSwD+1VkJ8DTs/Th3CcGmIFuEJiNhPbTJEttZycbZ0R6sUGGL97HvtbiiSQ1LRpRnm7h1wg+JrOYdgTJIWCwTS3dC53u+rp2bF6tvFZCOh59JWUU5HuRT0cEX4j9FyYnUOfpxqIeCaIPe232idFiCaeuBjA8OR+iOPBjAG5yQKcFiVfKpyxhdtpdp+dkoBTW/mdrCJ+ROYypPHvgAXRQk6FuDGqKYmqX1/rnKujrf/CZFXUDWm13qICDu+IDgJlSKp0OEIZv2rWB0R48ZuxAvCSz4owwa+mBlyTZA7i9RuRMG814/CEC4Po2t744qLb+bldCnEwmDUajslY/VUJqOEW6OIUSmDABhhaj0xnXPprn2D6URvjp3uFV7TYFzhVom8qtUR6brzdkwKTDMOnzTO5l5Q+qJ41hgDwL6fP8ncwdBAHFdJ4CDIntlJM3WDD33+WUjgm7mbmUyBkakuN9YkmXW7zUqbDCpN3R+XGQjfi1kzWRRGcknMgyvSjPxpH+nrD/Lwaa5c1OaSvJp9GXq9PT/LDr66a1tpp1523iHOgM3JiRRHvtCDz87fxSteNL5xQbaiDjvjhQbKn1CsdcltiG5sKpB+LGYru7cEy9txzqnVrtwpVKUgFzRMy6setlzJzQu7hSoYCGxI4DAWOtWYKrk/Q8mdiQiRqlIlKm79JaTpFf5BzUe48Kxc4htPmV+E46NZaiC88oG6nxul84/1GZl3jxDKCD3W/","layer_level":4},{"id":"531def32-f496-4527-aa66-895ddc7ac7bc","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Frontend Architecture","description":"frontend-architecture","prompt":"Create detailed frontend architecture documentation for ApplyGuard PH. Document the React component hierarchy, custom hooks library, and state management approach using context and local storage. Explain the styling strategy with CSS modules and responsive design patterns. Detail the PWA implementation including service worker configuration, manifest setup, and offline capabilities. Document the build process with Vite configuration, asset optimization, and code splitting strategies. Include component composition patterns, prop drilling alternatives, and performance optimization techniques used throughout the application.","order":3,"progress_status":"completed","dependent_files":"src/components/Layout.jsx,src/hooks/useCountUp.js,src/index.css,public/manifest.webmanifest","gmt_create":"2026-07-23T01:21:36.3286914+08:00","gmt_modified":"2026-07-23T01:44:40.3472777+08:00","raw_data":"WikiEncrypted:rJ/rIw0gVau8jPGqKFBAsMR2XDSFypkKHZQ6YBOgiECOtpjxeTIDctgQDypcHXj7kWhM29lH4ncuB1WibpCOXkrAesZfcY5g3zI8bvApqqavHZR0FFdrhDRndMhyO9yIQxVjY+a/ONiirQKAYQcJko6Kj69XmjVPoT612DtA4PjHu4tES9Raaw2tXV1tp4Cuzflp3difqFgPymbuIyJ0xgC9JARZdQap5C5XHLVDTKAf5uBUK0Gws9A0K7Z/dB0tHh03cKPYZisGDEhAS98/4pvIB1Cqvv8UlVO9YlWF4avKo7TrexEQCWQIE5xZPjSsPwrh0BgUmeOn97D5S/fCQZKCUKTHECq01gNesM6pXx2VLhqD1U82h/0acPg9n2WTf2nLEpn6CkuF1u3JzVHuMS46w/KGy96NRP/TbG4Ma7t8yjY4LztmISJ9Elepb7OkVs8GJKb/Cf4tMJe4nPwQRKKLJWYB6qbsDEyp5zW6KqN475CUoEPfrFfO82ket6xsPdJBdMo8Lj1jLiAG3PG9n9P2ZVhSzlsl74ynvcsgmF8wnkMVJz83LJQ8U0nDklfeMNwDoDZEiOtbBbYgIwhv4Jz50GhliRbLl8ZymX+zf/msYAVw7t2hsVpF0jZxJR25Vn5noxp2hdwzM7NYs/W0/nCCPp0ROXxoiPuPQngxSDzV1VFnUHGK4qSA9mhV26kJA3zRWD6WM1x5kHAMCpoitw6NPaaCRMvRrx924NVA3hF+QHwTlvYs5ieFG2Sbcfo042Ommb9OCfIFlM1hVHoM0N1nRcthYQCTfgEho57UYxbsfef28/A51PENAxivPIc9D5IisETy5rvZrmtFryBo2mHVyCK0lMwKkGE0jPuIRhWivKt9ushNnHYXtq4R9zdZkHSYsO6FccAdspMTQxCCcUDDjsR4nUo8jJ718sn417Pjg8Z07xIAnfAjBnIlGHSncVh4XiBLstruYYSj12VMoXchzyr3ib4j8yVg4GMAFDhUOY+UUw9GdQPeI6/unlyQ3Ig/zyHsZqAWXrb7z0Rj7ocSBbQOhW8rZ6C+bMwEG/SrZ8vNzJB4FZ6oDh/RapdZ117lHd/JL2OL65gxN4EvGM2KAoQMM7rBPzKCgXWwlMtcKOyCmBiUxv3warluMkMY08vtBWsENtp+vVRLsarlxVxEuzOZqc7QvW3hK0mjWurrSVmKp5i8jbcDuspXiaRrfUxKbb2DxOlWKmfm568byFSDE5fJ58G7WRV35Jeg9v6mVvo4/5QFDzUkZx/S9b9ZYJXyhfMk5N1YpTUiKpCWhl6bgDNgsAQDX8+d+PV1bgOruLyrh3S9s0MW8P2ntaDHNIyAhrhm1I6my1WoUQZvQqAkkABl6ARfMc3DP9CZjunI6mdjfHuFTc/GhSy7c0OE/D4futINOAYfeA1jb4sbAmK+559891T6dPXSF/WXKwbrjCENiBqLOpeht+g9+Daj"},{"id":"2bb031d6-69e4-4dc3-8dca-10b17783fa6e","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Resume Scanner \u0026 Analysis","description":"resume-scanner","prompt":"Develop detailed documentation for the resume scanning and analysis feature. Document the file upload interface, parsing algorithms, content extraction methods, and analysis results. Explain how the system processes different resume formats, extracts key information, and generates structured data for other features. Detail the sample templates, validation rules, and error handling mechanisms. Include examples of supported formats, parsing accuracy, and integration with the broader application ecosystem.","parent_id":"564369b0-e95c-4c08-81ae-df1e1ba0bbb0","order":3,"progress_status":"completed","dependent_files":"src/components/ScanForm.jsx,src/lib/analyze.js,src/lib/samples.js","gmt_create":"2026-07-23T01:21:42.2685139+08:00","gmt_modified":"2026-07-23T01:29:28.9053271+08:00","raw_data":"WikiEncrypted:j8yw4eIMpvYmsVxTwcxtHd1b3pr4DQprz+HdmYpsiRRLKGK+99Mn+M4eHIbyMD/GRkYgNyNgGRABIBf+kGtUh6/idTinMKE9hAmN5GoB/kA2djPWlHGULQhPWzU8voRCw6LRnSGz7Dp2a7taZ3Mu0dgMlvCODjWxMtWOkMCBXSP6x+fwoSq5Jp3rOw+K6iy67vLsNDub0zhUGf2zUZlePj/rtXBFqBWg+yeD9wcoRH+GW6T6iwGjGIUloiFWVzpAOk+RSOXowsUi9U/aaLyPtLz19BP2U4yzAl/nOFGHsvtG46dwg7oJ/QHZezZ/kHi5m8+b0uL8oiT8SNc0uH6t9me7wlZA7R95Fq3ai43a5RiVC5PLsdCSIvLlerDfLXxVwSQ38c8gPtvWbsThZD6PQ/wMOT264h7m7HxzfWtG8VHGJZ/Ur7pkI5ksZ0UG/2NDvPfLGeMv+oK1CmqMO8++8YoYkyR+LoxO4dosMA4B1Z/Ucrfv7HndDomsQ//b5y21RvD6VyK96T/dOSXoTEmvaU1DctoDYDT4X2+caIKV1B3AxSehF9u1nF5z/arChLlzjKY7ba6M/6rdEZZppKbdgnAb5GiplMQA9AYhjL5bPA6QCTcynW2aTwrIAwzGFrh6h26t1sh7RJvRg7DkGP59YhqaMcAnscFBN77z6FCEvTISTaPJnO57w2skaBDlFbeappljth41w4gQ/Qyr6AoVgy36TwDaa9Lwrjw5Yaq0DDORg0t54MIGvfDS7/Ika2pdyKuPLtCBzrgO8qfzvqJLadaHL8vko158ILjHYqJNmSOUxU7HhWbWfnZ78VqMNZDw5Wm3BxaU/pnGPCBhpmpXX+UPKoLqCSeOeyMprOx5iBKZl4g67bJXHkBZzMwh6LPfAWb1xOg5DmTUyxZ+RGmDdnIoF9wgw6QxUHWOSZVqtVSfT2O4huV9s5Bvje/+qCumEyWMtsp8IL6neLpfWlGvY9bTBynrPLgZmK+QqqvGhHFHUxWeRTg6+k4jVsDtYksGFo2syFvLoor7MFMKbR8opqHd55wZdlEvnR1/DO5rVKItD+l2uZY0M16ni4BCF3oDN4y0IZYH/aDZwByKc/QwS52Pfl6xYnoIr32f3+2rPtPP/+v1qJqgRz1Ux/CgMJ6YIsoJWpw49qeZX+m5J7DgXjXs9zGdYKznOCkvLdV3MQgY19Uu62wpRVBqavK1cPay+0LPUZZDx41QNo16H40OZA==","layer_level":1},{"id":"fe574ffc-5503-45f6-8775-410a5a8076ec","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PWA \u0026 Offline Support","description":"pwa-offline-support","prompt":"Create detailed documentation for Progressive Web App implementation and offline capabilities in ApplyGuard PH. Document the service worker configuration for caching strategies, background sync, and offline-first data access patterns. Explain the web manifest setup for app installation, icons, and browser behavior. Detail Capacitor integration for mobile app packaging and native feature access. Include offline data synchronization, conflict resolution strategies, and performance optimization for mobile devices. Address PWA testing, deployment considerations, and troubleshooting common offline issues.","parent_id":"531def32-f496-4527-aa66-895ddc7ac7bc","order":3,"progress_status":"completed","dependent_files":"public/sw.js,public/manifest.webmanifest,capacitor.config.ts,src/mobile.js","gmt_create":"2026-07-23T01:21:46.2883944+08:00","gmt_modified":"2026-07-23T01:29:23.3340099+08:00","raw_data":"WikiEncrypted:UqCm3bfts9Sg7qd9vIWABBfwrKSESt9gFTa1YkyDyiDCODJtR332pQ056g4UQsMV98b1vIhzOcnCQWiGy0vAYWEGLiurzPUCMLItIPTKgnXZpQKBZM39j1ctuctTzFMijbHRRHs8gkEIOn4ffaFRkUDZkooV8DoP4WWr9ONz6VFInZ68xPMWjDK2v2DEsN1atf5YRfGGRKidK8S9r9L/ZY2R9yXIPR4c4tpnOlfmzSwOiAM3IbMZyk1Vk/ul/DG/R8AFOxdkOmtNGoBhVGynw8GKA5FbGpMxA1DQfbkupFOjHOnaPBDKqRy+aJxfJ4mCrWXf7KGUhPgT6pev3QAJzgK92VnCN2gl2wwfXPVdVV0C58LZC2jAVUq04ttmauWndXmSCS72E2Pa4Ybwy1Bv0lcS7Ion1xIoG+9A38UJpxRS+ojI1K9Bnti6T3LZlx+CK/bnGjt4G9vhBkB9fjajlhghgqzMFYMgcyr3H7w7r1RAv2NufMLGHXkslIN+e2Ci5cMLun6xm6YTOPT3OFnum+lyy4SByHuUeabBo8owdfyTaJ6uMDBmJkQIAlaIDwiFnGRwITRNL3JZUM2jI91rE6oFiMsm8K/oAJoMw9eTJZPKVtJBqNnlvkAUbYX7qrOFa2gPafjxIO3BdGWX2YyjQpalFkyZcE7TF+slo/0U+dplKXeW4rjjucMHC2xxBm3ueSZC+NH3/rjB8fYO7m9JfX9rCjGMy3ngdLBp+WJgmzrvqQWXby6gUfWDQ1o+mYxLjBUcavJl6D1quWNvLOdo1u15nVwi170BalDTN3IJI6s1wvPeh6ZyDnKZgMLEdvwWGMpT4yaYf67hk14663sGjoVjSwS58mvp7ftbhL8YnzkV7nYNRLghErdzQq7i1aRk+BkuWxR++NaQ19JL2vkEE9ooHcs6rNLc6bZnhnJ/vubmREpRqW1QdAzFNAOS5E8VIK8EdPVyYEPlIDBDb6V5qTRW64nGlTWMSMcdpxUKfJdgN9nNq3ppruc4WOCOp3rupUNVeiW0sRfxi83gwz+iJk1HM9vs++mrTkTZ8tWx4k4hIcRFn8s7vEYKGjfZX8ZuNAXHESEigqc6GAWFSHsGvnFLgG7Lz8/Vy9jUeTWspLFEQfEshbGyYZmqquYA7rmWj4EzWnfEP/ABgUnlb1AQO/NO0zRI/IqQCNDAyiriifrnNXZbSdVldg6pXwACLlhydR83dwlRqr4+bI2p6CnmGs+KO8L9f0r3MdI8/GNREpl/CRTymgbiRXJd2OaM98qTzrNpmwaJvQeB/06EzLk685weZuN9jbi7LI4+JUG7edcio2ogRUXMWU4AeTDGzFcEpxaZ9+zJjl6f5ZQD/BbV++06ValeKCNRB3pBvRMGC4LYGXP+kdQH1Z2rwkBDxRMzRs3Ggu7MDZnNoQsSClom17RiZL+Gu8fLe0R5Z+n3bm4=","layer_level":1},{"id":"a12988aa-3acb-48ff-b3d6-4dd559e17ac5","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Data Flow Architecture","description":"data-flow-architecture","prompt":"Create architectural documentation for the data flow architecture. Describe the complete data lifecycle from user input through local storage persistence to cloud synchronization. Document the real-time sync mechanisms, conflict resolution strategies, and offline support implementation. Explain the event-driven architecture patterns, state synchronization protocols, and data consistency guarantees. Include sequence diagrams showing data transformation pipelines, caching strategies, and performance optimization techniques. Address data validation, error recovery, and backup procedures.","parent_id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","order":3,"progress_status":"completed","dependent_files":"src/lib/sync.js,src/lib/storage.js,src/lib/cloud.js,src/lib/followups.js","gmt_create":"2026-07-23T01:21:46.772083+08:00","gmt_modified":"2026-07-23T01:29:40.1617783+08:00","raw_data":"WikiEncrypted:PGdHQOrMWxh6s6galmzx681q8vcpfgJDLKkIPt+w3nyZXbrd06gk3Kb+QbP89JkxawdI3rQyv6b4ke90lWzhMj5rcxZdrDt47jv6EoiWBY3fBsOSetihTGjrS6dcxJv9PsWcp5KwOXZoEjexy6sF9SIOPfYuzps74hZpBM7T+hjrEaGe54twjw3+kFlPGQ5dp8Mndeq2iDBOT0p6pMTrgQYPg7eyDtMQYUzsLnB7WickSn1cVvwZol3YkBA1BJDMti/Pw0Bhqz16JmFOu5g6MhkP+sgVuIKPJYvqtzy2ycILTnXUMVWAK4otk/Blb0/F8NazXJRQ2T5+autghmSfczBSKzTdHZqtXKn+TYaD/qlBSB9DFdTU3dNfYfC2Mzh1WL0YP5f+063K/5i1uFHMNokJ/wF1hWtvvNIgVa3r4O1X+mW6utUlizRsg5/VkdlxNtXMLOqHnejWdalnrC0m/BIVUpm6VhaU/zrmF3rhnqb5PSMyCk/xjHg+ClWpBl1aLoXT6dcaYb6AqsRQYf1Rc4aE4Z8wmYAJj9c3bTIAyVeDCKBHI5HPNL3XeCwfXUh3v8sZp3oxGenCpcpb3fmY/BVDPxvhQBmmPDIRidMYsjJZsSDIBrE8xRvl64QrDbl1R5gHo73qTCP8PxFvWeJs0olm5jQd4kQKHfVrz1Z6Q4fTtpk9e3n8PezRwcnVuTLihOgsTMphbWMcujLSFd2AgldOEznsQrvQH6q4F57apX5DxYfQmENnVQE62hZhEqLlqTkJt6UmMkwnP+aeZPr4vhDue2a3he1dIH2fFEsHmF1x66oS2VigH9G7w2xQq5rIpE1bEGpTVyR777QviwurFdomdiRbIy6exdI/JPLIGoHhHIKE/QbXniAkPfDD3bK+52VByR8Sipt+RAhZUATB3DDwpW/mBt+2Gj+RTo3vMngbrGrNYiZ18ULpG6NHIJEYFbHAr3sQY6GJ9LyHHf6exQ95HkGJAEtHzgfPuGHTWsd3d1p2kLFWVdzsSwrvLLr2Io11DFtarsbo6eo9Ba6ETHJ0CucxXRratyigOM9Soob1gp/1nKgyaoKs7wPiIrd/GqaZXorsfQhZemqdF5caYFl5bb1mojSjWRda4Ch2JRNj/zNXj2HF37X2+GKRe7W/gckZ4GFCESnaxlyIyClicf5yfLL1SJmsoG1q+xgnAVbajc5t7+7PLwOWM103Ye54GAf9lonzUf4rWhVcfALgIyP5wg2H/ntEds5uxdAMftusSHQ7DseEpgfLm+mYxGhhTP1NVw9uJLklSRVe1uvdIA==","layer_level":1},{"id":"59876848-dcd2-44c8-aedc-1c54b8d48e3d","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Statistics \u0026 Analytics Engine","description":"statistics-analytics","prompt":"Develop comprehensive documentation for the statistics and analytics engine in ApplyGuard PH. Document the calculation methods for job search metrics, conversion rates, timeline analysis, and performance tracking. Explain the data aggregation algorithms, trend analysis methods, and reporting generation processes. Include statistical formulas for success rates, time-to-response calculations, and comparative analytics across different job categories or companies. Document the visualization data structures, export formats, and integration points with dashboard components. Provide examples of common analytics queries and custom metric definitions.","parent_id":"1968d404-384a-4a0b-82f7-a66bf82b925d","order":3,"progress_status":"completed","dependent_files":"src/lib/stats.js","gmt_create":"2026-07-23T01:21:47.8595367+08:00","gmt_modified":"2026-07-23T01:29:52.6072374+08:00","raw_data":"WikiEncrypted:pYjAeNwRencjUB2+jbOeauTujnr8R74/hXxN+2BivbHmvTNUXkrMlETVzc8oJDvtDE7Y96wgJXIuIE3mWYAkG8FG/5beepzDyUdnjv9RsZsiOf1QoEscK5rwEj2fxD4k25gUCBynmmXGI3qXzx3wvkYzna2YnyuoENxgc0TkrEBwTT8EcS4Jc1GF7mMx+doffmJo3t9zlha7SQn7XarUbz8ruJuzV9ZTs6kL/iHppFTgGCU3LriNCxKltub+Xjx9YjzuhVafxY3vzj+2rc2Gq/L9SYNUCa6ph7mnSc9+1ffscocvY90q2FaNBAXkQCfsojqJfOQplT1GBiXFTkN5IXJJFhCO5l1pGjM3JaAYbMLPjjPbfA2vq6eE+1JBQHq2GIs7zWemIGucxz+Jggxb2nU368L+vdLE1hRM0Y5wwii6SP56wYA8Ot0+Lypb3xOPBLSjvLrZFtEzgIjWxXiNF2dva2aqHtbZlyXaYhxoRL537wHu/ZxCTmNyXU9vqTLSbuxexcwiwOVJqnEWF0NeNK0/o9HC5QpBh8L3k04hSK+HKXt5YA2bw04cI/iPcKIl7aYOzSMje+/R8WEtEK40iPTrxt3wxPg/B2Axn+vdDaBCfkMMdpIU0ar6j+peBiTPZVpJ8hWJ/mW4TPuxmex0DcGEqWuao8iaF/dIwlrs75wwPqjOTnF/UJquDhbSu/0iucudjI8NeLXRgq3+0o4nMjx880ZbnUvmLE8I5HLJQ4PcSykurkVMhjagY0CpU5TZIKPc5GdgVTF5hoXQp1nsdwG5CT1cs57759zgHC+nhuVrFdDfw/bBBdgqOfiNc/S2iiiHUw+BjUk1hJPtbYtoa6vZQH8vfNUrgxXge0xwJw3WyNBJPM4SPi9xiKun587ER5cON2E9fjuy8QmfUOSYX65AtMDCQZ/VxMuW0OyfMvBKmtQHDLSRJBJs2goLLiY6qRs9A/7qQWE6bz0jqmgXmf/UdcRy/Z9/1cJs+mGnvmhHPQWw4ccXXDwLDfvcey4LCOX/8279t9oKvzHr1iK0JZIXIJvg5RASX+TsqvDkRxCahwjMHBjxdmHXUQUS9R9URI6UPm/wGkujs6awUYMdHnZygalqjvd+sddgTZqkJlEPKUxsrqx0xxbGbzdvoYUla94qJwx1dbEkA5q50/S9rt9ySMQ4vtCzX/glauKALDoXF8PKNkqoRZXSu8LTJunpN89ATPZHyeEaHzESS+ul7Coj7K6SU4zPbMfnZz93WdiWnle34sZQFhvarvMtN9NqcwmjHniO6t7wnlPekGlbY8bsFPDInIi64dW9ofPRTJiSmV2ihelgvTqNP8ZQFYVi2sIU7hmh62WjBsPB0fnaXRgqmPV379lKyD3Y7YonUz4=","layer_level":1},{"id":"9b3a12d8-298f-4abf-8642-26f50ae4b972","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Data Sharing \u0026 Clipboard","description":"data-sharing","prompt":"Document the data sharing and clipboard functionality in ApplyGuard PH. Explain how users can share application data via URLs, copy to clipboard, and generate shareable reports. Document the URL structure for shared views, data encoding/decoding processes, and access controls. Detail clipboard integration patterns, formatted text generation, and cross-platform compatibility. Include security considerations for shared data, expiration policies, and privacy controls. Provide examples of sharing workflows and integration with external applications.","parent_id":"4c08a624-9311-45cb-a77c-0010b16eb5df","order":3,"progress_status":"completed","dependent_files":"src/lib/share.js,src/lib/clipboard.js","gmt_create":"2026-07-23T01:21:51.7728084+08:00","gmt_modified":"2026-07-23T01:30:08.5331128+08:00","raw_data":"WikiEncrypted:yP6vl3GzzNMVOI7+ToNUFS7llvEE+E/yrCOdQt7bGC5nOHtUvrCWwDuIjjHAVPiqaMwdNVxYJP6NXKrOHK2tQK01tRPg4vcVXY+mCTtytlvqLtSS6GRceAYTX5So5okogS6z8NXJ3wxWVqHhoWIeLUPXxl0Z0r8MbXt/E0CuP8h81XUP9dUpow4K4GtDYs7DNxz2ClfZQXpSfEgb3EfXY6YgS87KeQEQGu4RZpKd6Mk6mdrrPqesS7krvfD5Duq4WG5XtNIeKS9Y9B+FWGAbb469b3zvh4HVIaJd4gCz0LdbFlSN+TxbbTiDKuUKW4CLsnAtmBtOVodvdChZygF4jZCyElV9TFzKdVoH5O39sRnd8LQiFOANRn9IROCfyptN+vAT/IYYijjPA/wSGAuExMeRRk0FJ/9ZnC8RQIFhT57KnQbv2pgvC2JKsudtDpw4Fx2dXeZtImB0WmCxzXTZKWRpU3Mip6DBjZouuoE0BKqPrOW32ilEGDK1ljVv4xDTh0UNTRqQs3I3+Cd+4vhlfBvrL/h9+oVk79sujJjauroDEXq08WFv9u24awAoKt6z1iQYd6nTkzjy7jXNFaksdJbqzt00Fi1OPSiN+W4uDL2/lvzp3XRaIunb8GC0Bknx9Mq/jZu8hpQYfk78JDea49Gm2q102ffEF26savJAkQG8GpfnzJwuweBJchQ3gRRDOMWaL5EpiZZvulING+02/hiVTpDuC8AoFdPLApqt/jhTfVIhme+jwSIHqeky3bGSQZkoiORMCPltnZqw5l5NyZZLMsYUWqArQ+brBYVD58LRdS0UYS8uwpQs1xoscCH1kvyAHdIKh+P7yAkipF2ijI0yfeDEkuEGqKacH3+2tVqCs8VK+UAVNg5HQ1Aw2m/PHttGwm1jHwToZBlifZKkwYiivcNegKXJFKT0QNcU0KFEut8WdW0GthVxZm7l6OnmdMLNpvSryizpXWtdhdEDX5mDB55uaFuTwYZI+qPI/fbavJSw7crDjk7+TOgR+Os/AMr7puYi0bsuru1rLhir+uJbxttSvneiOLN0TzvSg1QNQ+3pvqYvJXaw/ZP+fRjWW7nBwmJ6xZA3OKFbjl0Q1mA3hPOa9kbwFOYT2tWTJuN/2nya7HYKOaRV1+ITeGNMrV1k60heCq4InN0c6SLzuQ==","layer_level":1},{"id":"e5770f9f-227c-4060-97eb-f9ed467c718c","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Webhook Processing \u0026 Event Handling","description":"webhook-handling","prompt":"Develop comprehensive documentation for webhook processing and event handling in ApplyGuard PH. Document webhook endpoint implementations, request validation, and signature verification for both PayMongo and PayPal webhooks. Explain event type handling, idempotency requirements, and retry mechanisms for failed webhook processing. Detail error logging, monitoring approaches, and debugging techniques for webhook issues. Include webhook security best practices and payload transformation patterns.","parent_id":"0ed40228-e6f9-4241-94eb-1ab69560f488","order":3,"progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts,supabase/functions/paypal-webhook/index.ts,supabase/functions/_shared/http.ts","gmt_create":"2026-07-23T01:21:52.5984035+08:00","gmt_modified":"2026-07-23T01:30:31.4855074+08:00","raw_data":"WikiEncrypted:CXQmuGWiFd8u2IfkusypBwYdKAywxMn7JqPgcw3nyorbj0swDLsM+b7Iu0H97xSdhxktrdtyVZxNeqChx7M++Xl+th05cqNVC2fEuBQjVY3Y3o2O4HxnA1xOXxPTBZviOOmnaDvSV9Ixq0QaVtQHF124POVDlbdfYrbOrk37QmFn/WtMKRLol7aoOVnkX6Mykou+teEOKXc1/vCKFKBlWUh7twj0Yg++ayWz45zfvhH5GaIDoLXxJ6SfnwcTHRhZdJqbOOcsispmJ+p96qys4rqzDIKG/UCrxw7HgHUWRaxeyBXr1eqDTpyYFGq8QPzblBxui7NUycltpLdg6Bg+VGQFu226UroLjSyw/2FHCak5RXdiR8UwaOSSEAJqJcZo8ODexgDqSFh/CBSyiR1GYKOM6BihhrYZVaroIzSY6FnSDOQFXfDMIXW6H8Jx2PR67J+gfk0eZAWCdzYChriNO+1RzJGzXEIlD5ZF3M/sdVniCw9YeNa8euA9MuDqiMoO5yzF97p1+iDaigVFtk5KGW6CdWdLiLQsrSWKeez4cedbLXXa1gA1pT/wZ1crHvLIBNYmXeT5cqOed6W0FXIUQze0DCZLJA0z9XzRMkTAuLUoPh4lwWLU3gwFS1dgmm9ursVCaM3iqOQGnT4uokPWk9l7QWvxsfmHhhyCEOWCnCzZQKTSqEChMnNEvEW3tjK5K/GmtEAFZxc63XC5oy5ln0YcSiVBLv+a/A1iYmT8PFmNDUpXF2oj/U8HsH2TWnS+oYjSzlDF+9qQ5sn10qV8BoiWPJsL1SystnfqRTTeJS4ugHI+arDulo9W8PUTBlfvkKzlzYomTMRWQdlXdgaSXfKGRhmZRO096LSvSuiKnG2JifELacq5YctCba+o+SrStBKGMXxraoQjbjx6l+d4duzonl6IrrZS7P1KUX2CWoSV79DobEF0OSJTjE3ovCIH2dOCk6SP1JQCh3KnyxYIhuFchj//xo1u4hEDF5JtdipXx6zYXJ1KhwIYHlBUN6M6nUdK8Og6fxvIbkAHuCy6/dFHitVSGTb+tHksiM36vMlwG08A1CTmWXkSsluiOC2EIW7FlYZpD0iByaT+YDH2Zk/yj43BVPFDbiVOSKl6Dz2mha8eReLpvqxHSusdyIDEJKh6oNqpLb6xkVE0IsWBWSKqhXbi1U9lSZn96IeoPuI12Nq5G4Jem76lrKVd0p9uLbGGQ18qL40sSGs9iJEd4w==","layer_level":1},{"id":"85932b14-1605-4c35-8a54-ec2a3a78e484","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"App Build \u0026 Deployment","description":"app-deployment","prompt":"Develop comprehensive app build and deployment documentation for ApplyGuard PH mobile applications. Document the complete build pipeline for iOS and Android, including signing certificates, provisioning profiles, and app store preparation. Explain automated build processes, CI/CD integration, and distribution strategies. Include step-by-step guides for App Store Connect and Google Play Console setup, metadata configuration, and release management. Address troubleshooting common build errors, code signing issues, and platform-specific deployment requirements.","parent_id":"7ed0042c-9ec0-43b4-a5fd-2e4537db9eb9","order":3,"progress_status":"completed","dependent_files":"capacitor.config.ts,package.json,netlify.toml,vercel.json","gmt_create":"2026-07-23T01:22:01.1323932+08:00","gmt_modified":"2026-07-23T01:30:19.8463418+08:00","raw_data":"WikiEncrypted:St/uSl/sRv6KHLEEHSBK+GUAXW2igx97Koj/oz7uLA+N2l2vs1JE6r8w0lYM6wuKHHEHO2I/91+vFp71VU+z2WAQB3X4Dcs46WVUfwWbFGbJC/rwL//pSLYvLzbpS+Z/y/Ad+jfQqfE8H6il64OdqnrnwL3DDC/FaoB0DEvNVmxUNG/TwF3Aynhcna6VAcxeClgYiowy6pQYDuTakdmNKL4OB7xEUngpzkI7x6DKoWpjmxne7Q3EboQyV3x8o5AphTLToiOyia+e1xWfQ4kISzlxWizv/EnDOAZbOf0Sjv3OmPv6PhMnf5RrCZoKIGE6z23Tt7uve4doTDOjV8agZ4DXwkdQmi3WdsIleloKgjdEWXm1kKBw0IWbGj89ql8+tVn0QKb5obi0CUECT02Iv8yg7jIPvAodZeD9DLcrRaGk8j+XJQ78+SS+j4KvT63RU/0bCYQy/hc1XUo1PLCrFCUVCsBTOibrBSJF/sS6rVHaU8wW9JZg7/4T4eLYd5D3WEpLeSvrutVomxYGaI2y7rUZBtHr8hC5Eg+wl8b51bj7MLf9Lt8OhaqeEbBKgjYKwvmDRp4179suVns5aIRfOamPJrvl+x0/rhgzqIW3FjYhC1NQyS7UIPNoPAiMkWQLh2KjlvhslJsEPbek11CqFcCP2mibHTeT2+ifW+clLRYN3cjHUO0a+VdrNuQEWmMZfXRIN+dZY63aOI3364yreng6yqDf1raTzzJu/ww25C+fqEALECT1nsbpfAQlcMJNtKKMjAwSDnY8DdDBth9Sqf2MxRetqad6eaZOy0ikTJtTBuaI92JXmnI445N/z5xBfR+xt1LYO2rN9pjuqUdPq0giFuX8n9nByjLoLRXEqgxE0txlIyZNtq8gFWvHDdwmlqeJ0R5pMnIUAMc23QhdxZjYjcvzLYrrdbOmz2jv+s6H0yX3AmKTC1hizfpzaaCefKy46nexyN8FhQ3yD22Yb3roKU1yLtolbYRBxlMIt09SywUHo8+uq6jeh+Sw6Okby7wT4B8V0PIg05k85Y/sgi3TSAVFaWDr7qop9bJp9eGsc+V1aIJONB6sGgC3BYFPqPxFp2Wco4cVFUrP3BJ3gs3xs2yWemo4v0ipWYGDq53xNI8NP1XmZMZUSS7Fm4EzC+xSfUHiG2vLlQ81yqARyUE1eh+gTlxxvCE2d+cZxdsAXocM3YTS1mA25z0/wvbyNoX7uk4hegXmMCLqxAcRmpHqOyUlF6Dv90VjYXIYgkLJWdjDL+uUQ6ZsBQSoPTGQJutEG45ytahI0VfO3Wm4CA==","layer_level":1},{"id":"4f94ff87-144f-46aa-a17c-fcbf9da47b9a","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Follow-up Management System","description":"follow-up-automation","prompt":"Develop detailed content for the follow-up automation system. Document how follow-ups are created automatically based on status changes, manual follow-up creation, scheduling and reminders, notification systems, and completion tracking. Explain the follow-up templates, recurring tasks, priority levels, and integration with calendar systems. Include examples of common follow-up workflows and customization options.","parent_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","order":3,"progress_status":"completed","dependent_files":"src/lib/followups.js,src/lib/followups.test.js","gmt_create":"2026-07-23T01:22:08.2119776+08:00","gmt_modified":"2026-07-23T01:38:25.9131902+08:00","raw_data":"WikiEncrypted:JIVOpbk1etlZOV34F9CT0/BzFpvm4qfEmFJliYtYz/YUeODLZrBx4qb9rTt1Iuie9LpOUVbDIP3HMtFCxduwgOYB6pVH830mulHrVWSiHnKRz3tNFzz/Y5C5IjqMZ/9k+E21B/rnzxppyhL4wL2Iwsx6J4G2fS50VJEx+diGRF4Sxb2DEM68sndH7/vivHibHgBrRZ1mvNKIQZEmPqCbWZTPEWjETXnFtBzNKFwV5DfUVBZOStrbNEOtekwWpBKtK0zFifSZI1GpgQ0/fEIxJ39BdgLwdlTCuZWLIyoUmJWxtUUYPQnHtETg7YsNiUAepsalnde9ekLr+WqEHTk9n7uw7Wzhgdh3iZaIdDhI6BZ9NtDhNvzfeQxhWJVIoQwkKFoPLIIE00H2Cya55CaNFiy+Z0Pfx7WcWn0YqxKA1v3V8/5s3fSIOJ5kZPZEUiKigqN5nN0YhZinFAj62lP1yJi2tYZE2xmSMN0B3XhaQM+upnSq/c2mBouvPBcKlb1QRGwKhTTsuFY0ThnKuWkOujw32ey5SYv2+PNjofnAscX/HZEBvXlxzC+l8IiO+Zdu975mZTREd2H5koJRCuT65CiFcukpMwL7ejON2oTN87wbXeaPrF7Ou2ZMPORg+nTAFrWBc0pbLFAY45+K12narDgVSNBIS+EG6wVmkiEKSvMXz1wj0ZJSQqAzvDjK1ATmAcahQ6pFU5lqXs8vFmgF9e3o6nLHv07V/eV5EtIqSsBJwSdwCXl016phdVvDJLBitooeuoAxS3TAORKGExxJtJ8zGcmykxqp2Mh8kEyLPgwEnwEOZplXbXaw2WBouuvmzaPUuuFzUYz1S2jPlLStZm3sEGDozIL7iDY1E7hpooMpX7XrQc9dXNbGai5CTwcl4Snj/aBA/TmgcWfLUJaDPnK+oXCQIZ1Ur7Ye0O/RRwUe20J+p3QnldLAsNvwPN/d5aKsJyI7OTiCBhy8TgTqQZbDaaATpwO+S06Ha9AAHzJh935JRtYRhzXIg28oMo6arDWGCEVOgK2VqQ92tmfk0iOQr1IX0nPuTdK1q1SYT8s2tWBsfmr0qbRR+pElVkH90b2GsPyBVLDxOaN0ptoEkHQMUpwi4lPaI/jRMD5zm1s=","layer_level":2},{"id":"0b49f368-cf30-4b29-8d2c-35444cad28f5","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Red Flag Detection System","description":"red-flag-detection","prompt":"Develop detailed content for the red flag detection system that identifies potential issues in job offers. Document the various red flag categories, detection rules, severity levels, and alert mechanisms. Explain how common problematic patterns are identified, such as unrealistic expectations, compensation issues, or contract concerns. Include examples of detected red flags, customization of detection rules, and guidance on interpreting and addressing flagged issues. Document the test coverage and rule validation processes.","parent_id":"e847f4d2-fffd-4700-bb10-98246cdd7d76","order":3,"progress_status":"completed","dependent_files":"src/lib/redflags.js,src/lib/redflags.test.js","gmt_create":"2026-07-23T01:22:12.6853503+08:00","gmt_modified":"2026-07-23T01:38:38.6533632+08:00","raw_data":"WikiEncrypted:DX1teTwUVOfs35l8M2XzW8R1pDUpcGzeppyX6a1IyY/ae3V4whzu5o63WmHZdAVzpSFowtpZK8c+6KIxMqNUlO2MTKjNY0xk0of7fMGoYUN9nTHUerB9aw9Ef3dEfzxn9oZ2Sx1Cw+vOmhOnSXF44McFxmzK9UAZ9VgdHHmL5HHHHRnNbWmrl5I8us9VN6UWCKt38JABi5zlwGRFkIJF6d8nXdqS7XacreLBSdDNjlfgChMmmLM+3LH0R2mdYqS/g3WZAbYUdxDULMjRAxaBR7l9XdhI3G2d+7SDVmAnaBpmG9h2yR6YhOdmmo0YHcjWtPx/mLvdEW/b4A8HlCDnRcEx3Ia3jtHpZf2E+C7Qy7UytqzgHrOtYQFOOk+4HAUO93kA4D/yE4CixAaAqJvDd5Ea+/4rrBu7/vjLdHe5/9zKCqOZTYgYXXv15KWZ/aiPRgnobtVqeEx4byopgP+PiKqjWLCFHviI+NPZ2eCF/jFjANOuWwXkqWQlKJW9tUfO+ytQmyL67KjEjsT8LDQstm3G9pHED00onLlndl8mxxIbW4eI3WMkc6tMiEH8g5/ORaq1FQrdUaXbi1z6JRxqe7bcEl3k3cgdyW1UaA89GKQkGgWncMv1gh70U0b0qDquem81FoIPtCMhIMnQsyK94THCkKaqt+TEA3INTlbv2+gzfz/54hs9qc8QULu7j2PnPDjrG9XNBxQbd+inwFs4Scwm5/CCAJiqJx6U9tss5bKLMuERAll6tTH01CeFzwmKRrXrQTuaGENmEFBJNx0gcJiKY7ccBPNDYDjFu1rSWNMO/Ee/Liyq8Egy8GuAE+rzermhxj7N83e6y14F6GaGK4lHLKbPLg8E3PB6tpU7YfeveqT5ffJKYSxA8CmduHfYqDOOHkJW/pFvBznPBdC6eyHAt6i7YLBTS1uEGBm+/xE9U2RmnB3aKJvSauo0gJwI4OEokofN2RhSHSs0YAuDsP3SnzLecu9fII+JvyNo/s6O1gDKuOjQp68MBqxArgY5hQXFqUOe1zv5igsd9jRiFXQUh/PH6R4TIUw8JCqaW6lZbMnt+9MGcOYWDVt0evDCOKJX9qUWQVSsQr3X4BGz53SfQ9dnSwEQkbzUb9MNIeJrorWOMpXBwjpiY+WNc04EqRTtlfw1cnxhuVJJKBeJkNmmvAl+8QN2B7+Hh3hZfbB5XXgJqQRVV9MyEUj+o6Iewl195/6fHWyBbiAP2uUenz93sXl4RaiD6YnpJGHVgQM2AihD5I7qsJ4rf7j7pCFeAO9hF7VTrhz/Is8p5pJCK+DaWgIW7LHRr/lwMf8ax6KdNqhca6oEqhDXqNCV6iE9SpvCbizJfId12ggv9QE5iA==","layer_level":2},{"id":"1d923c0b-a057-460a-8a42-ada60b2dab7b","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Cloud Synchronization","description":"cloud-sync","prompt":"Develop comprehensive documentation for the cloud synchronization system in ApplyGuard PH. Detail the real-time sync architecture using Supabase subscriptions, conflict resolution strategies, and data consistency guarantees. Explain the sync queue implementation, batch operations, and offline data caching. Document the sync state management, error recovery mechanisms, and performance optimization for large datasets. Include debugging techniques for sync issues and monitoring sync health.","parent_id":"15e41105-5f69-496c-a0c6-d162881bc0aa","order":3,"progress_status":"completed","dependent_files":"src/lib/sync.js","gmt_create":"2026-07-23T01:22:12.9638029+08:00","gmt_modified":"2026-07-23T01:39:02.8030229+08:00","raw_data":"WikiEncrypted:42GucIVlAI9L6q+fifwcxfcoEkALXr0wT6WO4w2V1ESqOUSwS5g8GKKWM6MD+a0X8XFJ4sCQ5r2VKyFifkWU8H/mf1yB1jmJmurQx8BqlljPJkEqizCpbXOTP9YwDJbDGncnqdPJN0n9PSURLeCelJt7DJTCLZGz8X/Ls0XzkMuQji6ZHhdq4LsowgxSSY6Bom8daI1i2Ati/+08CV74cXH0Woc9lNMiZOTbHFVYsCauuKSeo0c9K+4aF96Lw4KGApOPIM0Hx7qNnl95Qykpf5gF+gacTiuA1xoR+MyGvKGB8zihNYr0aQqRoVRPvjIWSFZ7DDXTgjcz2zmYUzudT/dtyCATVe5+VoSJBrSJo0KzDudrysa8FmFHBgBL8q1I6U1mUh94VLYrvgq+ZTfixYom6cGzgP/sZW5F2GnQlRUIDfGWjGOGEgLtTm4/sjoMDN73jTPiTn8nyzTQJJQUiUS01xrpzWsw8FJ5Lfn8LG2G2q6mklF3qbiHps5lbrQeG5X6IXcWx3yQ+vOzAPFb7qcERKy2vKVrnfLpcjapYr0vOHvjSJ2F7xAPf36aSas+4CE599WfR86Z6slyeFgelZRUNy9jrt2Nbm06AcXtpkNeXhkjtIc+InlXlg8x4W6K3e56BPFsUqObFHPFK2Yy8wc8wGsVZliJm3TSjsd7p69rR2O9/7f+52nuI98/himzZhb57WS8r1zxK0sDr64X6j6Q8ziYRtkcZ5ecJyDi8sTnq8LZSfwNS5c3Y0igfjPfpLFvzRTmQOG8bkh24myz/VpoJBMbN2I6UINXHJs5dCHYmQgSKv/Z5Nwk00XMssViTbWElOyp6RuLPWxM7DoydS7lALzgJprK3ubHEA/7Bh9W1kYjcRvIkO6JdS2Dpv1C4RIsa8U3IPNb8XsBL39KEzf/M6DETDE74lcsYnHcaX9L0lk2dN2WLmRx5lzZ7pgvAZTeelIbeQpb67zFozrQ/mfdiBx9EM71TBdkXwzQHBnRFSVcBf6ShGV7wWs8czc2abEMjO9bSssafrUDdybU2BShEq4NlevMY9Of9wLfWac=","layer_level":2},{"id":"58173afd-65cf-45a1-bfa7-dbd35bfa98cc","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Feedback \u0026 Utility Components","description":"feedback-components","prompt":"Document feedback and utility components that enhance user experience in ApplyGuard PH. Detail the Toast notification system for user feedback, Settings component for application configuration, and AiAssistant for AI-powered interactions. Explain notification patterns, settings persistence, modal dialogs, and utility functions. Include examples of toast message types, settings data structures, AI assistant conversation handling, and component reusability patterns. Document styling approaches, animation effects, and accessibility features implemented in these components.","parent_id":"4e6884c3-ec96-4738-b40c-ddece5a2a3a8","order":3,"progress_status":"completed","dependent_files":"src/components/Toast.jsx,src/components/Settings.jsx,src/components/AiAssistant.jsx","gmt_create":"2026-07-23T01:22:13.6910331+08:00","gmt_modified":"2026-07-23T01:38:56.8095225+08:00","raw_data":"WikiEncrypted:rXszuFxm7xzNkPsi9X1qnaAA6qCI5ALJ2H/rzSdD+gPn1WxyYCinOBoGL21fuvQbaILBcjE2c6eN08XqYQ4M5bCugtZD2veeMhhg7WRWg2zvOV7pp99CXUZK9UVg4WgzHweSBR3QRCR0yAPmhoFgjNsyjMMwLJp5W/OVubRz/Zdu1+o5Qan1g+0+20ZayRJkdowHYdaac9ncuXIlOk4fZPdrazz3W/aGyH04V4PEWKmwtGIL82fAq32jPVWnuj1LVCMKjgQ2jqzaBhIdU7m7UNfeGh9UyD1PhwmPpbYlYXr4xtwoVVDBo61VVbtuiClgXLq0iCtmn27w5gh+nDSlkpLUUeqDFz8B8twYnORpDhiHhNyjImy8d7jfiNQugjy5SZgW62l+Jst8wJwyxQBOeFDTyQHEVReQDqj5kdo2KBTaHxXbPrCdizBsPDWuFXTZZS3JV6CBAkmTZG17JbVD7LZfzN507lFbc8PXosv+/atgP4y5174ZWyIQfR6+96P9+CC8rRXHspiyeGEq2ufZ24MqQWBFWdNgMWFxXUXHcqQ+JiOJAQEvmcqRVluSaONc5LYwBhoe4gINfXKBUt3a3QB3SOjNXjMpLFxsTEHrhxEXQhU/6gXq7MdLwv/RJOgBxyMmQdZY8Ch6TxZ7A2bB2+KLch6ixecACuQUurM2nDoOltOxkAFUzkBx0ChPx49WL+Rv9ugwKLBOqaZJoDP1DDV+4hwDAlLACJ+YwMnFKn1ondZm35F0W3lJdZ3txjrJRmAZeqSBiwKn3Iitg6RYWuQZ3tcaFZGCR7WgAfgnSSxjm5spXqauKvrQ3dJTDaQppiml8TWMmzyeV3XW8FVDoql6rBY0kdU7zvfDS/6M27g6GsBDrEfmGNLUqceayGKVa95tqe5Xkgl+lshBweCHPiP4J14jg19I3Ip/+2Za5K96ZAhcfH7GoaDdveZ9F2RIcAeW0KU531Rxv+jAi7EE8HkAwW4sL16XVs4UjPuWVbbCNgebo9eOsFSmFf4uZHRwAnMz1YI1ySDIdtVUG0roXSp4/GyUsC6UijOUTdHbRdRYbgp9q3KN9Pm91vHy48KI4haXsIlEeqTOTerea6D+sP4VgQA0pLLFtpW2f/UVafVww7SFd0IVjm3FjVrGGlDK3vuMETG99cYVPARSTBUfn0bJAbXU0dDgRlU3AQw5IdYaKxNkR/Fim0IlZF+Lqz3JExa7GNBzSXm5r+BL0ep+HsBhHAm67SfoTGuTxZ5/TNnstHobIfQAxUNE5yOFWKsgSx333az1pGWLowaFRURi6yNi+QfAC35wCLHURzMB/udzyzwqiW7ret1UvAMjKp0QL/M4s23UejSb4igZMEihvFyyKj/nRuzPKP/ivQBl2hjcwz5rJsK2RfcUdF0pIDO2VR0H4vq/uhPZfl/fKhZ6FN0NKLbTo0vye9zlRdEGglo=","layer_level":2},{"id":"0b725424-d2e1-4ded-98d6-7f9559db2877","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayMongo Webhook Handler","description":"paymongo-webhook","prompt":"Create comprehensive documentation for the PayMongo webhook handler function. Document the webhook endpoint, event types supported (payment completed, failed, refunded), request validation using webhook signatures, and event processing logic. Explain how the function updates subscription status in the database, handles duplicate webhooks, and implements retry mechanisms for failed processing. Include examples of webhook payloads, error handling strategies, and debugging techniques for webhook issues. Document security considerations including IP whitelisting and signature verification.","parent_id":"45127b67-19f5-42b0-b44e-63fd3d377aae","order":3,"progress_status":"completed","dependent_files":"supabase/functions/paymongo-webhook/index.ts","gmt_create":"2026-07-23T01:22:31.9828256+08:00","gmt_modified":"2026-07-23T01:39:31.3228145+08:00","raw_data":"WikiEncrypted:cX4Cq6ycqUrOaFkgcmNdXymKQWn19e6JkVT/QbTnFEoVBkbUlep38cQOdzBPe9EffihEv9KWBZf/Wg/2AvBGR6vwEsQZTh3fRx04hsd7SMUqIIaG2vH8P/RjrKA1cVxau5QzYD2aeOSc/m0u1rgJkGsCBrlhg6z7JxwOP2bcpZzgb7EGBa8amtpkprYisUc6s1ZDf4aOjzJWpu3W+WTrBfY5YUMyD1CeS8YuABdBJrqSAL/iHAV/7EN+ZOxvCZlH53tk2pHbt5NWQuL6L9ZluQSEMwkrmKLXVdmfFZEFnOQgPKBDW+nsWFWbHVWP4bDXzliHdYTcPuZYgt6GoYOwQw8opbzD60/YNGtI/dzelvD6uFHbM4nj5EYX4NAdNrlKZQUn0xE5IwGeFlbV7ea7wvT0udJhR4zcUdWc7a0r3lgtdfLaPJqOmCwgog7+5KWx82L/x3CUJ+d9VQznstPsfH/ck5ygYNIY5g1iDicseMKLv4i0GFHTOWtstt2AosfOQOe5B45aZ9Owx3/yHjUyzXlXrFFPtpN3ph9PoB1stF0YfM00aCL9dNu/pLMLSQQ26Apn0YJoU76x4JL+RG/sP9UJ+eqE3jJ7bzmE9jPfk2UVV/nKw+Kb8HXgaCpWKrCLqd6vAyx80gqiT6oC7aq8+yaUSrP7ltpQaIIQsIDsL/jlnahJHjUTiyJzsHB10Xhdx7a26543bKKma+rVH7zmlK1Rh1BlIqctbMiAP+qPQqmhabF7EVCHL0pQcUK1mIzoKP+q1VB6O7VY7YAnKONJSX37joerQwu0Pz2TDDdccmqEH/aL94b9fZgNF+3+WM4ftq4Dt2t3AiH9pBS6TBnnWhyU6/2wgD8uls9rw2Uf78b0ZG8J6hTSpdiHjx/gNhVHSRhT2g4OOux1xNW/rTZcRP0CBpdr1S1QaPs+bWJNRLUj3KAh8TPzrHfBpeGVXB4zqNRK+9rvcWPxZJczwM4aTWeMkqgN5YaqOXIxglWOoK/718CjfJ8Klg43R2+QNNOoAnY98dTUA8RLhLt6VlfOSkq4nQWxN+WRFFo7Pi0MmLikB98OY6i3uajb/IHsSmEmKT+n+RtIhRU85cHY83bpCLzIWJdOWCji29mfq8APhbDknsZOhtHrKx+mUubsbZvnZGTh9FaJAw6taNV3QXK7eNi3mLgQoUbw7CbAmBY2Vh0=","layer_level":2},{"id":"ee40670a-f27d-4dfc-bd60-c47ddedd85ef","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Utility Components","description":"utility-components","prompt":"Create documentation for utility and helper components including Toast notifications and Settings management. Document the Toast component's notification system, positioning, duration control, and message types. Explain the Settings component for user preferences, configuration management, and persistent storage. Include usage patterns, customization options, and integration examples.","parent_id":"80cd19aa-ad84-4b1b-b83a-8a34a7c03774","order":3,"progress_status":"completed","dependent_files":"src/components/Toast.jsx,src/components/Settings.jsx","gmt_create":"2026-07-23T01:22:42.738593+08:00","gmt_modified":"2026-07-23T01:42:38.1611738+08:00","raw_data":"WikiEncrypted:SvMc2PRoWqDcMfdzcPf97M5M5o6Rta+d4HlK3CDc90im7wmXJ90sa9Yw56jHoKkjFzyBVfBv+ySWpk2TVYsAwrsCWSB4AcjU8juj6CBOIYSnCxwn9fNAA7PqiyGyxrU1nzCz1zDGPHBocde0Zwe0QpJffib+lYrryO6xmBz9vJ4fimNsJwj2DsBNxxtwqa1u6y7PKD2ap7FJx3zT5Xhy3fC5Q8MG8FiS7SPu/bHUQocrjZ0sOAlDExoR6YTO+L9OSZpCfsQg4ySMlESuqfD2hMtyaBP5SHCx2OQSwzGfHlP4fmQXffhTYyqFqpgSd9NpCsNhhe0eAcQ8v+DgJ5CGRn8bQxkrXApRF0eiFazq0DCd8lpH5v8tmvnI1C/5EKMXMuPVG64475NCQGi6QsMg8BB0n5IygN/WqZvsMo+dd5VlbDddhfVAiOEu4CygbSd7CqAQoGaJEKE/RWw3DqfyFZloJVDgDaO2frLxodMJ8LZQM62vkULge4tI9BgH3J1+2j8CK4dZTeR/2UG4r9zCLQGj5cIa+lUZi490Oql7SOX1z20FqZQVX9uvn+BfnRGGZCBqW4NMc3+gFAIN4uu+ceRJg+WwMCTRQCEm46SCS4HU3lgFNRz0bjmqf3ocjy24pOxUIDRQRsJn+8cUUcVbvk4rq7DO+OS8DGYck0s4IZBr5tFB6GseFYGVuF1BHg6Ki3gF/nS1RbddhsuhKsMNWjlw1EyCvrJ3ZYnAde4nnwKj0jbILp0bgyonTEqoYYmTdKcAEauTmx9xjBk/amLIWinPiSar9Zcvm05PAk9zuhu5rlM0KQGOJYGnArhI3fyy5xNYRXoF1PFzBrDWm3eUDwZMeWKgqShhaNCXeniuezML1n+u13v38jrwj2eHHxnGkM0884g8HBB1yiszELSRQfXq1zFKdan45vEt5hVQaBE8nN/Y8B80BOeU/O51HRx7dikaihdK9rLEr6gw/KKqgEhfwyFIXCc3dtrUkruZLsvJGrJwFKs0fYzuDnsbOUl+","layer_level":3},{"id":"42596396-d320-4fed-9fa8-b285ff0708b2","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Data Export Utilities","description":"data-utilities","prompt":"Create documentation for data export utility functions, specifically the message pack download functionality. Document file generation processes, data serialization formats, and download link management. Explain security measures for data access, file size limitations, and export format specifications. Include examples of triggering exports, handling large datasets, and managing download expiration.","parent_id":"ae6aa76c-b442-42b8-8ca1-b2688bab85b8","order":3,"progress_status":"completed","dependent_files":"supabase/functions/download-message-pack/index.ts","gmt_create":"2026-07-23T01:22:46.6360444+08:00","gmt_modified":"2026-07-23T01:42:38.9596936+08:00","raw_data":"WikiEncrypted:ifHItXPwxlQbAA/KzCGtvkXbNV7Fdb0PJiKU6sM59rLfAF26E2CPlLtcGfP2mH2ZT3b4ZG3B/CaUl4/xLCS1wFzzfZkR3t7p5HWynYWw+GBBXNOFvOyS91/XkaB/h9JHNH5QrvmsJDh6xauwOYIwcDZXUGyMYkj8uK6WpMBUWn8Z/+uEYcn/YvxsiORQmy7Mw+koAKxHnVySBu/jpuVNrF4L18TOZSoLNEzXjvfULQlOGzsHglmAW46PIzmVEeLQWTpdFctAV7i/XFiSXRlpYO1srkj18ObyYA0nwNfrbT5vHOmNM/32GoViYb+UtN2Im1GGV4DcIM5eOJUZhV4Bj/8KQAPW1LjlCCjJUMiY3ZGVRKFqyGfR6INJ4Wmn8Xrj0UeDfdE06cP48B6qol4hwa2sCt5k3CPkFnSoxMiTsKUItReRcccItKSAKouNWLMt4iT2dPnEsxd0Jk7ZXatbOxGCmKraqj+7i2hlwWIxvtTL16NAFsbvXREXTKoAC32QU5ulW1ZqxF+RrgiE9yqkOKZUUMuq6JCNMUZe2i4ubuo1Z37YsCYyvyEfhnP3k0Uvd0JfBsNXlJaGOgFDG0FFVvegQweqgjKxz3v0aBFxeCVS9mqd1jc/HeQSNlSAE8ubNX7ygHOwPG7ReLP+HTj0uWiYiW6e7nbag9SbNsFZqO8yxiew4JPZV8GES2NBsRufDCUVXmtf2IU/WKDIF40oUjo5kFQThyeBDkaRoH90w8etAc0azbLQeh8S7GXU+ZxBP9Cpw0Sq2wAzMih+zgN46yEI2guJ0WGnw8AO7tJUdL0fJD85KfJW37xl0a1/aCh3Wan73BG+bmdkWq+HUiYxCA3YdQsHDGmGIuLXaRlEXXXtOfqsvfVYvheyyqe8DQHF4h96mWpjX9htUgjY6mjNecX91bskshXwQxIHurLJk481WYjYewnlXNl18iIaw/ayerC4mAAvlNyLOkfXL0NREZZnfyc2K3G7yxsld7ZA2xJWm1PkQu4XX1N+Tx4T/i7T","layer_level":3},{"id":"dc6d0bd1-9d98-40ea-af1b-3bdbed88d863","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"PayPal Webhook Handler","description":"paypal-webhook","prompt":"Create comprehensive webhook documentation for PayPal payment events. Document all supported webhook event types (PAYMENT.SALE.COMPLETED, BILLING.SUBSCRIPTION.CANCELLED, etc.), payload schemas, and verification processes using PayPal's certificate-based authentication. Specify event processing workflows, subscription lifecycle management, and billing agreement updates. Include examples of handling recurring payments, subscription upgrades/downgrades, and cancellation scenarios. Document security considerations including webhook URL configuration, certificate validation, and secure environment setup. Provide monitoring and alerting strategies for webhook processing failures.","parent_id":"8c623eb0-3465-412a-9717-f8413bae5ca2","order":3,"progress_status":"completed","dependent_files":"supabase/functions/paypal-webhook/index.ts","gmt_create":"2026-07-23T01:22:50.2757272+08:00","gmt_modified":"2026-07-23T01:43:19.5557846+08:00","raw_data":"WikiEncrypted:lwC7d6wvFUcTMCQxUtXdXqC6eMdX1fOX9aAmzWfN54SUfC//s+EX8CcLLlpnw7oJyA3MqhwMNUBCw+xltfXlYOeikiQMhmuTEwuxscvGATYp6HgfUQlPWhdQNCzSDXxt4Gvq971VulW2a1OnAzFnL8qhdnHtqklbERNW+/ZfLHFRpmjfyMonO75XsrUtRnfUJsSYrKP5VHlyv/d957xC51LmLY3XK+K0GxR+BIuxSqmMUlDn7mPRzY/3Ef/I75eRTANG/4WpvmwjO3HFI9uJYY2UErtlnpv+BU1iUxJ/xJjwGtUVAWwPqDa4vXjdY22XPIR3lPGk728UsWzv1Ol0ubXX92UkHE8NZf62cA9zbBhL0GuuiWfKuEWNqvnDp+9KY9YdPa+//r96nm5QpjWsBjYoOWp0BYm1oC0a4IKJh1cq3RRax/W5WII7H9Srv/a9Q8P5+9euV1q5lah8bmLEcqbNrhwiJRWqrj/cUzqe5n9nrJRDLC+Mn0KbXEN0edTDJjYf/lQHr2wi7osiQYCVBM72tiLyKqbBX/1YVdXGNItiMnrbr/qy75c1wGrAH6D2a1BPzXeHIa/WNp2flhJKLmq0BIbw7YLvWj6BxmwVwRuvkkVFDEC5ISGYGFf2Mfd8uYVngw0qdG1XPBJILSekPniBl25KOgxxoGhPE6bGz1T+4T9tiO/eCD7XqS5oB5gioZPmMFMa2P/cg3FPTlVgt0FCWd1ufqrY/8JTsW7ldDBhRFjuh8IU4sWgaozIJC+OrKmuXnbE9aBQMe5AUIDYeBdh5c8aDVDvcOmQV57OEx8gadTBL+58mH1GAtBJvfybNsdRMOB6tbC9VqrZ/bU+pU7zCsBNfqqa9+yzEDDiY+IEBp23bWjZbAduhsf1h+ROM2xwBxhu5IDt7gxJSSzI+flojvhGc3zUMItJbAISO42k5ETIUKl8pDPtA44cTNEimHKNFVd4FQfBrODdQQJ3hsWyp1eoCKPRtg5F3AQj7Rs3V6OqgSmVZMBwQAo4oC6+TADcUdFrxMz1GYKfINXsA3nNgdJYFVk0D8KPAcGJcQVOTCJq6OCB60kBLuSug0Ib2o92czMZkZx9LkJw/7R32LxQu6lWqyGteRcLdlkKJgD/PmXq/POv7+dgQ0ZjH4uWJhJz4KZ72IkniNSljgg2k6nI06tCDJAJWfYbsOVXN5i7G2QDNHM5f+ZgP5uFsUSyARxNCqDFi+wkrbRDHqGbonefCGkqvBdGMErTCFhKjQwIApYrza3a960iyhBb10bg55HsTc3tqbwij01ADNIXeld7KTk4O7SVlM6nvL59nayrswRQIFM2+qb5z5hfAWobytFLATqRFK4QLbZ834GYcBK8sO/hq4sE/kAYnSMFQE99snECXwSCUiYZl/zCDxcXoXTebuoMmqpcWRv0Na+Zmw==","layer_level":3},{"id":"564369b0-e95c-4c08-81ae-df1e1ba0bbb0","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Core Features","description":"core-features","prompt":"Create comprehensive documentation for ApplyGuard PH's core features. Cover the job application tracker dashboard, AI-powered interview preparation system, offer comparison tools, and AI assistant functionality. Document user workflows, feature interactions, and data models for each major feature. Explain how features integrate with each other and share common data structures. Include usage examples, configuration options, and customization possibilities. Address feature-specific settings, preferences, and advanced options available to users.","order":4,"progress_status":"completed","dependent_files":"src/components/Tracker.jsx,src/components/MockInterviewPage.jsx,src/components/OffersPage.jsx,src/components/AiAssistant.jsx","gmt_create":"2026-07-23T01:21:36.3292166+08:00","gmt_modified":"2026-07-23T01:45:26.644252+08:00","raw_data":"WikiEncrypted:luoNp8LvFa7zGThvIT9T4gfD6KbzJyTAydbcRfVv0b4ipMir7bDcMLDQzSOEcRtlGF3LseUbKUQSZy8GFXzEwbQqYe35QM9UzFB8zhCfDRDumUsO18DJ8NJQJz1U62w24rnaYxkAn+uiOEXokpj7K2LJQ8YtbhVkf4fnASeOfFzRicDQaCotuGNYHJIkBnDFIAJ5UXxhoCrO4+i+7aCDxCSrXi1D2SMUCOe7hCyIrwBQX2KF23Ha4zzfYl1daR3iBdFkdTBFZV6pJ9or0VwoWJg5l4bjOHepuQatBUUWnLsML6m+MtqGKtsoV5dIZVzbStW9+x7cEwBflg00CERcW2FT4+F17n+IGV/R2XtuWfs2OL+nQxHrdyq/G1g8WU54V3M+FEXBrhmmrlULjsL+DmuihXx/XhasqMY4MxvadJPuNWoJXHf8frbou1ZHsYVj2WLgz1PCquvl+B20vhSqcP1i87UxjMN0RnDOh3n49HmVd2+wCxCmnr7d8FszTWSjD5GW+d7ki6BFeTZV921VCZCqqJzlzXr61FCxjyxWIzqIpqFxT40BzerO8gtRhGWt87emdmZvDDZvlcuHdW/Yl+w4f9x68OrgtMNUKQCyQyAIIUBOtrryjKf7pZzvTfbZtfUVLjfHISEZwZZAqhs48GRyb5l+2wOl7j9avLO7PCYHWwCOBWBephGjlqdXrdy27yLWTGrGohEhtRBVP6/OdPXBK8ebKb2W0AULlMUV7zOT0+N/ALSlBcriKOJdzwl8K+ZjBWdcoWgOiohK8WXiwT5vwaou1IKExgfSEbLNzOZyG3hBEwXlJs/bzKpEzxyBcf1pOSqbZe+UReqiWhfr65kF4lYZqhU1crt9IvZdTEjyU3LtKnSO6EKORUdGmh7n1DUVk39WudRyxivoEDlPW2+MsW3qn4cPGjN4hY1nV1RXVXBjxJZYVRUUXsGGVmAo/7HZk7H5weHm6f3ky0LKjYImQ6dXo5XT4q+SbRFEYroB9l19tfb44ftSaEMbvUg0CD2On+LUINXO6K2gtnzFPGvQZnB9QdXMzrMUqPdQyVwAQmtWrNeW/44GF7o56OggJEoveQ6F94GAsxUJkTtOG+6ZdATdPmUHjGFUGZr4XMotX7DMhWeVcSgG5fBykUVUqisj8qpvidKUPREaTKKKe1jGgQMYUdYwlOC42R5BA1EpeI44cc/peDIah4p32JOnJP4iqJjqJAgr1Dq0NB6lWglGPA1TtEnoXWlPV0OQRrhGno31cI4uaDgTFrMDzJ9ETSkFWxrT+kQkCk10IUUviVbnDCzpnqns5Hnjb5W+CEjTza2t20qc5V9M5oz+uMN4Vr/Mgqy8RLTSIkmfLK8v45youNzNIoZLpuI6RECtPCOXjTb6W1luApm4b/9pXhN11CWGa+GsTdd2D1v9ZUX3lTGOAdAhG/9khvJfHSwKhRc="},{"id":"9a77d4ee-ff32-47a2-b746-fc508706f196","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Integration Patterns","description":"integration-patterns","prompt":"Create architectural documentation for external integration patterns. Describe the AI service integration architecture, payment processing workflows, and webhook handling mechanisms. Document the API client patterns, retry strategies, and error handling approaches for third-party services. Explain the subscription billing integration with PayMongo and PayPal, including order lifecycle management and fulfillment processes. Include integration diagrams showing communication protocols, authentication flows, and data transformation patterns. Address security considerations, rate limiting, and monitoring strategies for external dependencies.","parent_id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","order":4,"progress_status":"completed","dependent_files":"src/lib/ai.js,src/lib/billing.js,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts","gmt_create":"2026-07-23T01:21:46.772083+08:00","gmt_modified":"2026-07-23T01:30:51.2778976+08:00","raw_data":"WikiEncrypted:0j4RRfWJQdenLQLpT+DwLY9h0ctWLZwu8+2HoqcoTgehYjYc5zOlpxKqahTWHGyzCqTow9jh6bCUkxXJK+K8RR1IPDKygAilTz3H8cOpNTDzbJ/qMcwZz4oNgn0FY8vto0XeZyoYJWX7oLNLEpj2ETIZZVOw6LYQYrPWQfTg13u2B3k/EYL9Dr2GJ+M1hWwnRCBfVMl+9QqgIgSjSJR8wwTrWrfnEWgzgqWMPHtDNq4JBGpX6CpaquUMLXG2TlMoYRLClBRba07gNlna6Qq92d15jcHHaOwDrLEiQsCdQw6at8csLoWlVrev64ogx9HouAgaFFwpkH6pMugPOw0GfNjwZssZqaASYXAZsRR0QQjZwpwz6biSLlH2NqaIxTY7qgY06z2n6moXCLfiW0h61lg7PF/UTFjzaUHcd2qe1ZwB4lFBEaBS1oEIUTbpfu2X5rBE8n8Ntl4VPRgW1xwqG1BZ5QVlr2pT6OJ7Dp8z4zgStBctix+88A2TPwd37/IThMEC12475KhDN4Tbu16tFNhgzlCoAUrBZL4rpVSf7e8xHNNbg45VwT8TOmTp20gaF/pX1cw2nvfHA80no19lUncmtjYdb0/mNDZWVGHQ+cfXCBATjiULX9ruscyIeId4UuBok0/AacG1A9J47voEBzd+iMg3iBaY/EfXf0JNeziMf1z1em0O2WbbBV2EINf0sxcMreMco4UN3a9XbWi2a5LIeniID/MlFczyuHHuxbWhfFqYuygDm+moyIncxIDocAlOlILDBOuYPPfzj6ppUOSyqSpp0CTGXSDXFiOEX/4SpHJ6TqGL2OBVY5Mi84rrHLO8NLHfQ9zrj4QFhHgWbHGSc23gg3v1wbAM/iIMb7GJkqop7oyHwbLN2jBMmlPE70iQmDWFniVHizdyDTJEFRtAbi+vKQHxhRXzgfTqWY0ipc6p9QB33HiSgE27PkPaJCNRt2mRt3fmTITmyzNU/xbmC+7IYViq36S7lF/s/uLIHfR5Wnlt+5zayMR9YCREZRx8LDO3QexFKhcTEl1DVaHteew7aB1mPtdy1H5zVwP4MRRBa6t1fOEBd82rOqgt547G0zG9dFd40Bf4pYZhMa+Ec51bjZ/HN20uWhn2v8hT/ijPxcbD1j3NU8FZ7S9Y90oGNDl/jdJMAV3iNza4r+6EO6VGLwwYUc5XTPRiJF9/lNUUtyasPTBQ6YdkT+ju1OJTRVsZCgEebdcDx42X2Zqhjm3eAgeh+Sy5Wc4F29eIEW2Sl4mpBVi7nk34DtZCc5VIV1mWYRY3naWRYyOSpLK7gtAd/Q5p9t9Ksh1GaEHqkJlWXRITudNpeTwWTLo1S7NoNBodEtvO1SVPPPF2um7q1N6t77gbN4T7Da/LXC5Pww7CuE4jwkSeLgs5RhhSeKjSp3EazgXvLruRTWKfWECnr7zsAfZZAuvkNIYDC7D9TRE4GQzqHzq7GEucqEMb","layer_level":1},{"id":"827f407f-f618-451b-bd83-484a188044ce","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Next Action Suggestion Engine","description":"next-action-suggestions","prompt":"Create detailed documentation for the next action suggestion engine in ApplyGuard PH. Document the recommendation algorithms that analyze application status, market conditions, and user behavior to suggest optimal next steps. Explain the decision matrices, priority scoring systems, and contextual awareness features. Include the logic for suggesting interview preparation, follow-up actions, application improvements, and alternative strategies. Document the machine learning patterns (if applicable), rule-based recommendations, and personalization factors. Provide examples of suggested actions for different job search scenarios and customization options for user preferences.","parent_id":"1968d404-384a-4a0b-82f7-a66bf82b925d","order":4,"progress_status":"completed","dependent_files":"src/lib/nextaction.js","gmt_create":"2026-07-23T01:21:47.8595367+08:00","gmt_modified":"2026-07-23T01:31:10.3816278+08:00","raw_data":"WikiEncrypted:xnybntKFAXXjJIrcM+6gRiDBk0qpmzHAqGkf5YQXB0h13+/4SSIYxXU4l08advSC5BSi6LS8j5L4YW8CWW9kYW+0ELV/PyBSJUS1S6Ki8EN8rFvQWUuDIuISL/vgJLf3e5OlI/hleu+UVG+lGLj6rJRMDGfcKBraPllgnhspaBkcffKFEHYrEn9RCgrzxIwzSkFDtcwW/jF9MT3RtymnlsJxyAYfgBQIPmufbeKZKhs+d8rOUrKGwzLuaNZ4VMqPFcZOvRR5N/QdWXzYjVok44mhl2CKEdU03GkQXWc7nyS1Xu3w0+56ZmJ2uC6jy67eaEgxFvWDZKPbj8M5q4dterxQXlcTLSKItanJNFcoDgPPqGwhK3fILBLr1im3fCASe5wC9ioRLVxdRdissYPkOVy9hFDMHduY/HGtRohepUYbDgsGFfUu6M4B7Xm6ap9d938IEgHF4caCBC9NGYt8Uaq1Ep2ke/udv8Bom+HFB2yWp4tGOIqiNU6mPXEc5+Yo0OGux8nCw3Ajo5POEFvHg4wr6tpGdl0e0Uu/L91K7HyKLA00fXBP8hEXd8XYK2SqAyx+lgo090drEbUsttvefW9UqzlmLktbFewon5gXcyPRiMH+UoRsUKYkSSexdO9qGeRipNRaXXOBDNURN0CdCY58odXUMLeryez2WU4cQh6Bq3HwjfkjLTMoFXSCcdQ8LXVgHeicUHigADSJETmnpmmtlrPAXIu0sRQtsXRNJWBoJipXNbuT75RDf7QSD+FEUfwd1lVHDCeR8nfXd58zPjKqmqQ9tDssSLRGz3CmrheXm9Jt7UTs7lIUSEevjo5yulvp6OKITj+m0jiNXQsce8iCCIbgVaPLfEX/bCDQ6n+wgPSdbMb9Ki1iC7fKxTQKe5RSU7mdx7TWir7XHdFMMlWNjWq2Yee+2ELRwnpNK7T79YanLN2+0SpixUDN0p7zhBX3tQkKZs+1lnwx1VPzAwOqj/Ebx9p41xL0l6VuqX1OXUq5bSOdl7V3kR+RQvurhTe15HSdb5SgUuKAyem5OQtio/vMzFA2Z2dyT6UGKh1YgYNd6PohfW7OrgnsjOE1KaLqhGmZoLYD4XHDRrNgUK3Qm2sveH5JrzX0dYgI9HpTFuasCWTGAffUdI+Dz/wb2K0iQGh1iR91Gmeq4Ar9bDNHwfH7Oyr6bHj7UxVp8iTkk46WzA+fmnJwigjxroGH4HY73DCK1zFZhsIIVVuLLGjttlIEnJRQ5bN0vLpxTcX+qSaO5xNlXRgicLyqSDYdTFhVRaiCN8x9htRx/ft45ZazXOAlaBicIYVmuf0gUxg7b/F40yrYceLEVjghq0ImaY8ZCPvNsArDBGYa7xuNOUQJzAqe9gY/r6Lfnx5Tif0qkz0U9oPmeYiAF+FowmMUdzOr9P5UruIZFtiw7qD0JqchaSneFwlliym3qWxKP4M=","layer_level":1},{"id":"103637cc-148a-4d2d-8b2d-f3a47935286b","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Analytics \u0026 Statistics","description":"analytics-statistics","prompt":"Create comprehensive documentation for the analytics and statistics features. Document application metrics, success rates, time-to-hire calculations, company analysis, and trend visualization. Explain statistical calculations, chart generation, export capabilities, and performance insights. Include examples of common analytics queries, custom report generation, and data visualization best practices.","parent_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","order":4,"progress_status":"completed","dependent_files":"src/lib/stats.js,src/lib/stats.test.js","gmt_create":"2026-07-23T01:22:08.2119776+08:00","gmt_modified":"2026-07-23T01:39:36.0592009+08:00","raw_data":"WikiEncrypted:I10XhDpKGD4toYifAv6+tn+QEFM1VUaswn46rDwkcWoQYv4CNR1UarW0hjHOLcuLH0vPo1+wDwWisII9pc+PmugPRhSOsOCoKcfWmOrkinFyefDnPJ8akmMvadlR+u7yNhgKNUxr9ckGpm7YXjaKn/0Ved3m4yUtH7zfhwg78IlBiH7Xz4B6iKcISy+bbE6Xe/0qnrRXDWSZg05/XRbv27H8jujbthUTYetHm0vzcCjQUu8NAtR0bBOQhNslHav8AtM5kBhVTBb6XU8gfrEEcFOyFeHycJJVczObJsy1jm+Wv0cyHrW4rbhnvU6GM55hfWH0v/1tn9eTCwu+ajJmXCvoAumcfsw0WY4HjzqeYl5yOKTyOFc4bRsEdCs+sUoGjbjzROSbJ4HUyVHzbsGiC24gW7ABjqr8eM6t5nfAtxiln3yYR6d0vo1hjnO3OvBB5mW5WfoIBcAd2nC1hB8sS8G9uN2Do5XdptxknPM/oa/Ve9YmokoTH3KGYQXKM/xCwLvhxCuo2fHUmGY5stFdTtRybJQkXIcDRGLz+cLe8wlVsPb2QotddgG8QfE/b8V6vEc6DL8uH9PMLF8jkmNxSVYuQrQGNbhI/r+W8THzKCHNAiT/XDzJuq9OOjsR+gLm9fYsEX+YBW460g8cbFTKFYz+I3uKPk1hspkzBPFNL07z7AH7t/uP11X7RM9Avn3pHgJQyB7AHdrRXjUHnqA1lI51CKzcvxOnx+l2sWlsYZqkbthLEmLIqEjpkMxd42//thwWHUqFCeixlRdWdxmTQNccJtZ6MIlQSwiYh2RgvXzyMKQexR2BrGQXEaOcWtr4VLTmOrxsVghjaJJqp3fzssLSVFqUCiGITgasUbxNdptUI8GEPUzyrAWSgxdh0oYr4DGKtJZZ8haHV4YV2h3oOYkQyivvl4De4XIY8HfzkKNy5f0TxMruo6lNIqfl0LX52PxpqynshjvSE12aXzif+J7IwK9YTC6k8d/MI9VO8n9pkOAERrhYmF3Efo8IAZCO20U9IfUZhW8fCo2x0HlnaFu4BV9xSASmF6H3uXVPCZeqa3id1sUCGs9g5Mjg/a6MKm61YGt1Ily+9gLBe3SPQ6/SKKe+jJnO7wwd+UbaJWc=","layer_level":2},{"id":"6426aa08-8de3-4d15-a0bb-b4b8ee0c4d75","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Utility Functions","description":"utility-functions","prompt":"Create documentation for utility functions that provide supporting services. Document the download message pack function for exporting application data, including file format specifications, data structure, and download link generation. Explain file size limitations, compression options, and security measures for protecting exported data. Include examples of triggering downloads from the frontend, handling large file exports, and implementing progress tracking for long-running export operations.","parent_id":"45127b67-19f5-42b0-b44e-63fd3d377aae","order":4,"progress_status":"completed","dependent_files":"supabase/functions/download-message-pack/index.ts","gmt_create":"2026-07-23T01:22:31.9828256+08:00","gmt_modified":"2026-07-23T01:39:30.8922867+08:00","raw_data":"WikiEncrypted:SvMc2PRoWqDcMfdzcPf97D3dm+kFZCH0z5wqDdG6Cd7YlUVSrkhN1TQV3TDMhuKc6vY8xid2SeYymlvUWAClvCtKbCqTMBhQCyzK0WakyrtDrmmHqTsJmqmQRKBr+tR2jwHpo80aJ8jkYtDlrBYeUhPG/H+eSu17nldHkIsUcxoL1Q8kToXEtoaHklwFF7Imrb0eJRKW6ZukHiAEfCDZ70zOUNW34ImtmO12+/2uYWscUWKCPNCcxX3APzDshOju71cUhEs8zMgVuaqPvJyPbILfLITXFpszLRsx76MWcs9j5+6biU2VuNIfUYj36GibZcPKZqZFQpPkKywP++x2DrElxwZ9/hm1mMXkmBCWV3NcIIz8tMK2Nu934Pm+TEhDaJc77MnVCSxNE0V0t2ecqtGkGrrorBcoiAe9WwfLzS59qLt/FwbCLqR+29F/aUjvdog7SX29FUT2fS/qL4KIS1Oh/c6AkBGFQ+tPqgD0MRreBY5tovPbTKmxfuty+z75O4KD8sAUomGFybyu5cJ9rRBmj3aTWrXxqKHDJIZ4UM/hro1n4DRpWnRcztZGqfuosxiDdORvOMER5uX6xrL8Txi6pK3znkHsKd8Av2bi5xGCrHL48IuUSRBz8GAimFu8g9sT+ebzQlBSJDqlPfnS8lOgVpIjSGWTb2ZQ9vWyoVoGkeb2cZbi9lJOKHP355tjCR4nsQ6HZsQ5mmMCVnUaPybd4qCIFffpUBS7mHEvQ+3a0TNoV72hzU+dcQ2zOEUBvHU/v3WF4SmV1MVzqjxs13X+OG5UlbGFNDU546yi44Dxsze2DNlkNQs2GuPaLLEILN1+ah0rfe5jz+lxTGByRgzk5lgDoVpkeh02IJd7pxeVgRqNPjbhTuqb4Yq8wAn4B/SWPiXBXkGdI/197KekbXMj5WkVrCuJUEh4hNryrqNVv1lyybtDZCQtJ+QmHRly21hXaCbBMImkHQb4btcfVjFrmgLF9lBvtw5vbbCCDK9UcZS3xUJjf6nSFa6P0LybIeDMS00l+1F/MKMpoi8C0/2pSAU0iB8eVfdP71wePpdETflBCn9e/1bK7u8TdC2LbBFcSIZKfbOHzlM5dG4msA==","layer_level":2},{"id":"dcbda18a-c2a8-4b5e-bc54-cf01ba4d7a52","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Subscription Cancellation Service","description":"subscription-cancellation","prompt":"Create detailed documentation for the subscription cancellation service. Document the cancellation endpoint with required parameters including user authentication, subscription ID, and cancellation reason. Specify response formats for successful cancellations, pending cancellations, and error conditions. Include cancellation workflow examples showing immediate vs. end-of-period cancellations, refund handling, and data retention policies. Document business rules for cancellation eligibility, prorated refunds, and access revocation timing. Provide examples of integrating with external payment providers for cancellation confirmation and updating local subscription status.","parent_id":"8c623eb0-3465-412a-9717-f8413bae5ca2","order":4,"progress_status":"completed","dependent_files":"supabase/functions/cancel-subscription/index.ts","gmt_create":"2026-07-23T01:22:50.2757272+08:00","gmt_modified":"2026-07-23T01:43:15.7765837+08:00","raw_data":"WikiEncrypted:/qtkhP4ZGxGP/T1P8fibqMtdn07n7Wq1nmibfkJEiwwlUGuoJJaz1/Z5trV5RGGYFXqciORUSy+MwDiD9ZT9YrxAjZVMODyIynFTNZQPbtM+sZPIfE6W4C3cP5iRW50P+oSRvDsyFHoPxoziMeLrYkrZzfyykrCcSaJLo2nEyTKb+wy/mcQDMuz3z6sG0lJDlbPTkBx6mb3Whmvmjrh0iwpWbwrNrxiDXS5n6WJa0G/246GqjK9FYEjY1Dzjq5wPrf+rILEew+/CdT/GWk3e5fL/GJe/qsu52zbjKsG6bUZ9EVn2nm8dCXk/6vQilQH9d5oONWMxpLNKm/2j6GFhQ6k95qPNuz6lJD5yfQZf1YbeDF8riLYSlqfx/D3MrXq/uvgevkQ1J076ekRnHBt/rdossp+5Xy5mNZlW6aYh3xTVYp1ZxWQMBFX7KsFMHXc1rWtDX0EjnyyDpJWNZ6Q8x4OmUKXLVpjnglEORhZ///t3FV/nWqJeM98UfwRsSxH7wP3lvPwynQZTbq1W0LcNTpal3KPJFQrQDpx6+mjyD/9XijDrHY69Pje01S2lVCryEn2PKyQxSO/feCdxjy43mTZE7cCiKeZYvoxff5ah6KHCLQvkWVGSCR1DkCBwRUstLdB7/KsNSelO3us4LViaaekJcBfKsgEF4ordii24iQB1gbHTxi7h+zQxrMkJv0yq/64szjmBU0exaIWgOvYt8wT3wZjgLlJbXrhh40zRRWYYo44uIoCT5VHXuFpY2VrDgml/iDJx+eXQLWTZgd79DEPkG8Vz6KURYCe/RZQ4YO6QO3devx8qsvOUj1PafgnnvktsdRrsJuDqKjhkDCR3Yv3iAOKyVX+gEakOf0/Jc2rkElPtw/x2hlZrVnI4jPwpAmkHlsAcYIm6gF6gPh/7+W1x4imCDa0g2o4TOhmls0qdOnXdVeAmX8VU1+d5H1mg9FndnVDke+3Li2zUeflOEk1NuwepSnvNxOEi/1OFgLseBhhrsKaOBaLWm1nXLwmxKREiMO1VPIL31qwPMWRNiVp1r7Dxc4pr6ipPI7KN2o9VgMgQ9xtLYhRTnabbjdRElyOfmkfYrd5x1bAZsqI2cROqjypDo7zhp0ju62W2L+JJfgBpUx8d1W9lmV9ZGwPR93AykSIkpQ+eQtlcVtelMw7Ii1pwebmq8xqitT/9rDEwI1AAwqDZCWuv3VhX+w6S9vwOYL9+U4RbV8han21O1nKG4ynlSAgWGh7HRkvN505EV0sqpJ/Fjt8NzzdMOWmaq1dCtVZxhnrKK5ZBOgnA4vE8/zyB3w5Zd1yIhLsTV2JG7AeeTd7Y6nWWCuXRSiKAIul760Sq/gvDBQbNyzFnWms+BHgbvJ4tP5/LKLdvfwbXI1wydKBu0xufoL4Qsrw2","layer_level":3},{"id":"986ed762-453d-4ce8-bad1-3e06d2ae510a","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Trial \u0026 Usage Ledger System","description":"trial-usage-ledger","parent_id":"0ed40228-e6f9-4241-94eb-1ab69560f488","order":4,"progress_status":"completed","dependent_files":"supabase/migrations/003_trial_and_usage_ledger.sql","gmt_create":"2026-07-23T02:10:32.8107316+08:00","gmt_modified":"2026-07-23T02:11:09.1304787+08:00","raw_data":"WikiEncrypted:cj/pu2SfCXSUB3oilMsFKpJOSy4x7U8dBh7y2TXShTUQDtCb7Ib9lv3Zrfk6KnOsJMW1O7ypJvxZaSa7tdjHkgn/l127gM/7D009rEydb1LeNms6yAbVp3RhP3uQlj43czl62aSbZa23whAhTV+xypePuoP3L7NL9pbx0Z0PXh0dSDc+g//MVU4cAn8adT8vHOxIEq7yXXMZg6+7BavqqHCetIjK3nfdQ+B0wMGZ2IqEdOYA+OG+u+AAlBJKYPcMjWwQQ2qNKTWIXwLlLpMA979GEFrVbMYRlAsVnLdVmVE=","layer_level":1},{"id":"1968d404-384a-4a0b-82f7-a66bf82b925d","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Business Logic Layer","description":"business-logic","prompt":"Create detailed documentation for the business logic layer in ApplyGuard PH. Document the analysis engine for resume scanning, scoring algorithms for job applications, follow-up automation logic, and statistics calculation methods. Explain the red flag detection system, tone analysis algorithms, and next action suggestion engine. Include mathematical formulas, decision trees, and business rules that drive these features. Document configuration parameters, tuning options, and customization points for different use cases.","order":5,"progress_status":"completed","dependent_files":"src/lib/analyze.js,src/lib/scoring.js,src/lib/followups.js,src/lib/stats.js,src/lib/redflags.js","gmt_create":"2026-07-23T01:21:36.3292166+08:00","gmt_modified":"2026-07-23T01:46:05.2837717+08:00","raw_data":"WikiEncrypted:mHLzoBKW/ak+KVdbda4A2Zn67KoTeQt1oMP9weY0rUcgwi71lNX7u0TJCuo7GvWD2jdNgkYuRucSLVCH6z3NYtaLE9xX1DEtgJhjiVmnlA9vtEfTYUW9hFXiXEi20EerSch0qWfTn+3BV2d17WJmihk7ZZcLFEWWuTbvEa0sVgAOMny5tLMI5NgVcOv0o81vD3F3L9OOoqRo22Z0XfXCjBYQC6dWH36dFgRmEBPFp8iYj/oeQT1fCBm7dcBz7UqeDsvsuIDmWzqydRnJI7EViHZe/co8ZpEi6Y3zGq39GfSUxz1EBGvQW0ElL9WELWU3mhtVvdsJwWazeSb3v/ULHGDsZh0QwIKGLK9aRR/SkN5QPFzqEJEwjk0KkzvCwQq9Ub3bv07hyzl1K4KmH/IsI2ZlhTTZUw00Ax3mkQFr9HPyNR10J4WIbyyaHcfdko4wZhEM4qGFoRbAiMtdB1iAadPNMg5yS/SK1TqKBPrSrnQatXbgspy3Nkvz7lWGVVGLB++ahEYxZz7iogdg613oJbPNXTSd3MGwvpx2GkO+qIbLJ5jmedn+I/Demqu53QNwDmnNyOm0PFuzpYPD72BX39QndNubenmpo6iwjiwetXhnGoXpwfi3K9Wu09fz6E14KIrCQFh+or+F+p9gRqW5dDfWjh4NNM3B4bVyrsbdLRNSw9f62wWgLWuz7g8mQpSJkcqHl6zasOTHAna0xrrUvmiFf1nh3rSBJjXFK3AU78yQZEWv5aCxEINP+r7y7KIU1avQK0wBbuKEgqetVZjNdvlXdo1W3WeS/HgzMyNPal7MsgY4XEf91QyHMy0DJmGe2zAB9JQ2RkJLZLE8GgKM33qysQdhANAXd2oRONs6utbW3VSEmFPnC+4AQEwism82schUHhWY/w3zkrIS1oh1tLRkTAttpLqqWu3vs2mCYxExmAx3X98KHyoarQUbOpLtQcSgW8Ph6Ca5iTwNkZp2cPFpBs8ckXxE8THdciyhcvE3y91gCwynVKIU4rsdgGl8iPe3XQQFxcUVN5ZoEbhiVATWrfeLJQABi/cwdssQ4bjJKpnXy5icFuq8ewwElcTD6DHPlyMxKhPbYbxf0VieRu8/qvF2Me8rTkpaglW/xF9NW59FcI3No2p5O+lE66TbsFTRwY84Cdnm+NgZjMMhinoYP/CoIqhfI/PgKrxK4L/hIgPzk5LX/qA2PJeUrx80DtLlbWmNkJ/HjymGhEfir9J8c89wmRVhk3VnmVxaS63VI8U6N9HYwLf38g2jteX4/v9UMJgQkkeDVurB4kiRUOWszeUD68cG/6FScBQyPlu3jS90VefssFfa5vo2s45OZH5L7sCYiu+Uo06rHlH0ag=="},{"id":"9ccfbe19-1be4-45cf-9265-638ddc1b34e1","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Next Action Suggestions","description":"next-action-suggestions","prompt":"Develop detailed content for the next action suggestion system. Document how the system analyzes application states to generate intelligent recommendations, action prioritization algorithms, context-aware suggestions, and user feedback mechanisms. Explain the rule engine behind suggestions, customization options, and integration with the overall workflow. Include examples of common scenarios where suggestions provide value and how users can refine the suggestion logic.","parent_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","order":5,"progress_status":"completed","dependent_files":"src/lib/nextaction.js","gmt_create":"2026-07-23T01:22:08.2119776+08:00","gmt_modified":"2026-07-23T01:40:22.4086593+08:00","raw_data":"WikiEncrypted:xnybntKFAXXjJIrcM+6gRiDBk0qpmzHAqGkf5YQXB0h13+/4SSIYxXU4l08advSC5BSi6LS8j5L4YW8CWW9kYS1o7Hu0eI2zgtmaqy8uGhYz0/TegTO+LSif1SyFNCqB22CWE15NDsigIu+71K9Y4qWwqVrpO33+z9XbF2dnhyiFJoAC/CnT6dyC2PCIm9tg8/K4AMV7UjIFjDSURlyI6fdlaMyuxfitJNBxxFGD+r1ErfaU5DWvBRSmhIMxA16W67LazBe/4bygcRkHJsJdT+lRWOJSl2AxKj88Q8PjNEVaVfjL79PQWh54YKu3cY5sRY9FmSBQO6xZnqpCf0WPlx3+hXqjHvxpSqM/ZRj/dsCDS+2ZZq+R+L3INFFCEuyPJ19Ej8qVwsXjL5+QjeZ+mIExZZHgxXpNEIm4tKvW5JfHKJ4ZOnWW+Nucj0xzV6lztJx7OlUry6GsA0EzA5gRCeh0CMcTOkMcmNVf9pDH4FEps6C1I2u4HstQU6sksvTnlUus6ySiedhA8AutGGuWAzHVfxTWW6mK+ffbKjig0PpoGAzMQyjr7VH+IUXwV8+iaQyMXi03dSGciLIjBeeQAMdNLGpIxE2OGCtC5EFB6mbXylGdYOW5Wem8rk4Gf/GIRD109Dy9my68/S96UupZ6vwvm8C9mGoi51RV+CweoMraG0U7ipAxgB/bSfJBUDKleprVwP5iLszRGXozIlKFVb/v9NY+pULPgzaQt2QB8aeCHUjSrsi/0sHGL3mPRZ96JEYEBpI7MIFcQCqS3DcDRN3mZn7l19ApKrgwvllxComlUdYQdo2O7NhugWz/gg0a3NKUWphm5JTzDzUi/vOAx79/B0oF03sh07dZfW1JLykZ3Tt1SywgRSMxJtQYjWX7zZMx4DFC2sV8x+kN/XlyzmMoi6cI60I3GMVNDbmKSG4Yic9iYG8tiGhin65RImoVLa1h5r4G5aumrLUIvuMCaxfyPKQ3hTm/qme8ddXe/Ru2uEA7C4sksqg7YiRNXao3eM981pzq28YomJ4D3Ki4duVlRmhbl0YKVa5Dqkt81c7Y76hM4zxh0bD6ouW33bCm4iiksa9Xy3iP+0Dz4e1Dvb0aIrRyHcsyEZaGHiJ3uF2mPj3Yqjsg4c1OW0gTWzNV","layer_level":2},{"id":"4c08a624-9311-45cb-a77c-0010b16eb5df","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Data Management","description":"data-management","prompt":"Create comprehensive data management documentation for ApplyGuard PH. Document the local storage implementation, cloud synchronization architecture, and conflict resolution strategies. Explain CSV import/export functionality, data sharing mechanisms, and backup/restore procedures. Detail the data models, validation rules, and transformation pipelines. Include data migration handling, version compatibility, and integrity checks. Document performance considerations for large datasets and optimization strategies.","order":6,"progress_status":"completed","dependent_files":"src/lib/storage.js,src/lib/sync.js,src/lib/csv.js,src/lib/share.js,src/lib/cloud.js","gmt_create":"2026-07-23T01:21:36.3292166+08:00","gmt_modified":"2026-07-23T01:46:35.1757077+08:00","raw_data":"WikiEncrypted:klcgW2PbPxJambbKMzvFt0U+w1/T0i/lwh3wGz2PLUEUXJyCaF2cvAMjCiNLnta8dDL6zFP+ttDYlQ8V42SUjFDK4mNDh7UibiKpH0Mzu9y9c99Z/iTjwuj5p9CD64obwowtwQ8dbOrcdmnKRiF0zgNm/sUHQHNzP9f6WQLTrBOVRSqf4CWShUDtS+orBV8NzRgB3ddpDzmclzcWBXtii/oyS5vLYY7qwBikiW4WYs22Y8G6pGFEFVgsfgE9FE2xD2mp2WOkDTEwVcWl8VZissisfKMMeFY+A3xZDroZQbSUP+KpE1JXEvH3MrC7P/Sqj69wDsUfesFxrTBFI8J1xPoieLYK+JXwKGxrL1Kfuxzdsq4YYmCZH+eXNpX/ZC7sAYCLgaccA/w62i1ACtxHobEACnoAjW+h61jYGjPguSC7nWZCPcbl8ajs/SjsKkjSsH9ECSwuf1QYD9D8KB0ll2i3qwnCVYl9KqtE82H6Xoq/dEWCYp9iVLbjMlnQVW7EqkKpXupKXy/F5HGOVjiwQX2qD+Xh+cqM/X3A+Myk+AvtMv6zS6wOHH2oWli1ZRcfyJ4dr2358BaF0o3fgqbKJQUXwB26v1vvxne4WV8nt/24UVzfKYBNkkdqfo13/wop/Z/6QJpqdSVmkqohGGKlOQOOJwCWSlFdDYI5p22bgqHwr9+k3DXVNczjoxy+Ii2SkdGxoc7ZbGhS+j7pXeymElHZy0QmPKj8RNMELrh2509rxYwrmB8J5UwJUs6FRpbYAZxsVWXX49ytW/I6kyvq4jepD1Y3OovM57d2n5Lw1KnPo+b60EXSIWvYviMN2K7toRAvby3xF23OAr6CCvZ7KHx3l/4t/wIcdz3i/F+BVWBZfwitMotwagWoN2lARakXqSLZyGHXRzfyCUywR2sYVVTaVwc7w31JurecZaar+iDumWVSD2PSBLhRtOYOsBKVwU4hYhajWvYBJPubA1VYYfu3AQfP9b8DL7oikdf4mGmp9P83c4Q/QTWmk00k0KmIQllAOtiUjbRyAKVFxYVBCMh+I7Qoh7H0M3m18QNqUBet1bP07x4JsavPZSNniaYYoMUsksCgSbeYXZ7nyPowEZg8nAAPzA2dob1DE+321XQnMuVRUtT6FPY8B54kxS0QKD30vv8OnwG2nC1MOpLTGOjlNZ8GzbsUKhPUlzGcw4tz0FfWT/tEHKX34i3rmIxtq8xv+K2vZp36soGQIxDN/MrPzoApl/9Tv7myISJmYAc="},{"id":"6545bd99-a4a2-45bf-acee-bdb022c420ed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Authentication \u0026 User Management","description":"authentication-users","prompt":"Create detailed authentication and user management documentation for ApplyGuard PH. Document the Supabase authentication integration, user session management, and account lifecycle. Explain the entitlement system for premium features, subscription status tracking, and access control mechanisms. Detail user profile data structure, preferences management, and account settings. Include security considerations, password policies, and data privacy measures. Document the relationship between authentication state and feature access.","order":7,"progress_status":"completed","dependent_files":"src/auth.jsx,src/components/AccountPage.jsx,src/lib/billing.js,src/lib/entitlement.js","gmt_create":"2026-07-23T01:21:36.3292166+08:00","gmt_modified":"2026-07-23T01:46:53.538089+08:00","raw_data":"WikiEncrypted:uxAckj1IXK2TQH//kEdeBIzkl9Ai2GGydxla75Fs3qG8ZjSkRRkZr4Vcw0vWdRWrM1KQO8nihxoBI1uRu2tYKn6jCHMo1MicH3Hx948Gt9kzvXBx9Zho1egA0hKW3u2bSU05w9KVRFPzZR8JfWKz/ssvk4sXDRoEypthyWx01DXW56UvWdNFvo2OEjvUyshtDsz3I8+0kNtXYH9pO/kZaZZpEUSzpl7CGYX8aYZlSDkAngLflpYsXEUxOai4ebjM5NchA+zLQdCUXrY8bUD1MI4kkGdkm8EXbnCFi7Bj9LTUb/7LgiLziKX8iz4sQ+O7cD1TVKphFF//0wc8rUUK3MvZUPM4xrcBWojWeapHA/fqq813Uqw4mj+2Zop0eRzwCWiu2wyH3SMa1zSJtBRz2anBbcYIh1GsULXLYN5ByMeUfDMbdF6URUJGYO7bI9mXHOkPpvjn4FCyn8o3YETZNywxz/iPnXhze9T62efFn+VVJzyJ7pClFOav9PIcRVnvGTj0kboC7NDTUSAGvgq7ieF8s2znqUL+bujtadjPZmQIrlPxEgVaj4K2BLrHS9S6wE9x4GIV9IcrjONK1oBi0ncBgNM8h+Wfc2MxyfTHG5Qwozkm7OYIsLg1d8DFsopaHAMkug1jdiPVVFroHlBzfI9+kHUAcdXpjzJV85tNI9FuZKH/dKsnR/9vDsQXj0FQC0PE+33FGjv4SLcZCtSrPdE+nPiDuxuVouUVQMYdkeLeoWTHkxMbD3d7V+Dzb+mPjm3jsz6knHJIUNe2qa2t0yAxYh88OSf3s7pKcYgwJqqRrAy4mwnxE1n/hHcOpr1vMSqwpHy4zxKLn3KmoP3no0FElc/aP1DR8Ngzmwt6iq0d2UyZEeGRemp0iDYfs1ZIxM9ieVX48nsHWP3NDNv8e8hGFZSh8Hilj3mQI28O1WOo5El3CdnkZch0KeJdID0gemPyMLWbEWgNYVn32jG0nCy1RxbIIZ41xh9tFMeneV1GL0X7csg9JOyqHL0fT2QxTzHVSYb7om1R2vQ7qxgCbkKIOBlLYEyvfKR7FOtr9JlyPPG7Q4jQmcPqkXN5U4vdTDI/zgOnbrgz7sVJDYL5gCCqLyKw9G2WQf3tnIqpnNIlKNzAfnVRm0CMwtNTlvAXwvj0hLpJGIYa7sFlViy0kpLstSJfLHtTota19bk1btFpKZXUfjH9PC4C7VdsGMDXz1FJbPXDiGK/v8xG/MMX8K6oDdzAq8xmVMvGcbmHOQw3pgWG3AGMk5oTdBQPIkY5kJFHFmDR2EuYChP3+B2ca46pI4wu1QdiERuBGYvGj9E="},{"id":"0ed40228-e6f9-4241-94eb-1ab69560f488","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Billing \u0026 Subscriptions","description":"billing-subscriptions","prompt":"Create comprehensive billing and subscription documentation for ApplyGuard PH. Document the dual payment processor integration with PayMongo and PayPal, checkout flow implementation, and webhook handling for payment events. Explain subscription lifecycle management, plan tier definitions, and entitlement calculations. Detail error handling for failed payments, retry mechanisms, and customer notification systems. Include pricing configuration, promotional offers, and refund processing. Document security considerations for payment data and PCI compliance requirements.","order":8,"progress_status":"completed","dependent_files":"src/lib/pricing.js,supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts","gmt_create":"2026-07-23T01:21:36.3292166+08:00","gmt_modified":"2026-07-23T01:47:01.1275753+08:00","raw_data":"WikiEncrypted:4hzunLRGn1L3xZmJ6tNxumpjwqlzTlimEeZnv117QAAQCmEl/xwCgd9vPLLl8zYo/knmCWNt8/lMv0uRK35WMmteZJBe2mrk78GKr9+KDEn2grPtOCmrwPh+Yhg12TNx6AYw9jjcr01s7vFQDz5QDRz9zi1MM4Jk9La2Iuzell54Jo82UefDR1kBJItUVIjExtEQfRqDQsg0OlDQzbRw1djjojq5auNvOOn0HroF3TvfflNCuMA+AJ2GFJu0OqNNoLMjPIC6a7f7qe6MxKsxIW2ngrTixmiDjNJ/QJeysS2dkS2QGPNdwRbVfno+MyFSOPHB2T7zzElnPt7Of5ZCMxcSpZd9yBf4mQLc1f3mBFDVJGLgNUruFSfxUxfN2PPqd20Q56RMpEzpda+/phtJgKcuimkHLstQmepsOtTOMEFHtbQA6l+pLgjO5FTACS+AF+KqFZOXxzMi+NdCJw9lNcMeTfkaDf7gjXkwk3mcuPx/3ZF5sKqjhucGwzhSYtja+pR46D3IQcwI3GKTXmTL61EwelRC1WuHAaxD2GYtScefkpH9JljF+By/+lDw4fCh6lwYYmlCb/X8IRsUMksbIYAP4SQRRt7TcEUJVro9v8D6RUKdk20NC/JcwWJEjgTEkPfN+MExMqXzReiWoYF7Wt81lcd2Kl3uBPuT3Yk1iU6cypQ0hJrR1q3MVkaFOZPR20URm/8R2x4i+otBPUiUagGMcRckl/qGygs+y+zE3jPp4vMg/U4eogHnqTSXvoRVA2NkWO1pLAu8WXjo2JkETnO/YdUu9Qx0UZjeB6HPp8xbO/CzqUI+d07OAVk97aAb+NZXSLsy1VpHUAFmQQGe0nz5Q0kJ3tXyTPFdl2DYIXPkE1A6hoPCVhWzZGyDo4rrNtYF5tggbPQqZUnjwAdwBUOr0I2Y9df1f+FbmD8KjA+x1Rpzx7Yven9oTW81Bu5TJexwyClLHRq5OdbLfjshJx6c9t9Dx2f2eW6kfZ9h2ZN/h6d5ykk2ikLeu1giv7gwThwDQaRlNemiC7kdbGY6XZsaLaoHGG/nf4L2eWyfDCEUtTKkwPKJC5cdhIwFxHK+eN9YDQLIwBAiGNhEygw9eGF3T7/DX6ckINWeFr3ycx6KueIFuABDwBacM7gDgqYeBXh+3aLVQFoTVrKf8cXU+BWYWp1cMRnMYiR2jz5G/mZRuynZWZQw9w4cPAVGmd00Aiyle4DxIgGLdUFqs4kUP/qT/O715kkGRGstOtU410mgcr7MK8mud0eXsdjLDR1ucHswZ7nr41RICMNtjPeJlmwULnEnR2IPgUir53WY0RwwjTsciAzv6lQQmsZ3+1gvHw0mjI4IzY96a7msu/xk2qIUUEVdpwcpW82aHqQa4EDTZIVkSbubvS/smoFGdvxO2QaR9MXgvE1rhGeh7+Zww+Tc5ot0C1xDYG/VEiCjnCpPV2NugyHaKMuOfs+ZRX4m"},{"id":"915d9267-a5a3-4ccf-9891-2071a4e7b621","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Backend Services (Supabase)","description":"backend-services","prompt":"Create detailed backend services documentation for ApplyGuard PH's Supabase functions and database schema. Document all edge functions including AI proxy, billing handlers, and utility services. Explain the database schema design, table relationships, and indexing strategies. Detail security policies, row-level security rules, and API access controls. Document the shared utilities library, common patterns, and best practices for function development. Include deployment configuration, environment management, and monitoring approaches.","order":9,"progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/_shared/entitlement.ts,supabase/migrations/001_schema.sql,supabase/config.toml","gmt_create":"2026-07-23T01:21:36.3297905+08:00","gmt_modified":"2026-07-23T01:47:18.3953235+08:00","raw_data":"WikiEncrypted:N3UbzwGjCC3xD6BrTM0cq1+ibJD9DO06/3kIFUntt04tJAnGDcGsMdaXBg7GCggx/x79yUIB3hSdzHtFrCNe71pknhzGcnHkh7PBhLnd9fQhgo35LlrOP+OomysaqnfTn1VHjA7kkfxU22KJNdFEyHb9aGLKp/2oHOa+E5eUqLjJz7Pc7Pj64slrsCibGAXhTHNH4jClMowEF3bzsOnbzbkPiq8sQKeEmDvRu6yAgA9Kqxxi+y7Y/3HB+T4XEm0Wy4gSAKMSyFdYn+a4YSnj1BF+a7s2QoODy7uxeVoXG0gGfDbnVWoV0qBOJku6PWx8kCxpjw9VDVB8H1hNlItNtUu90Fy60FvyfQ+o/+9iJ/sFQzrpqeO2YberfHCVjxFA+obdhtqlgxAsd0SpzKAsm3NAnghvL2QFB/ZRT9ZCXDU3fzgXm7gO9WorbsSpXxtFpS1MBZzMU9twieNA/+a6uUFjFDqtCEx19VAeB9y6xcUyr5XVPbFaa/r7/14HecmLphAaD8p9KysWv/ExGtqR2sP+WT2tm0BqoyLpjNYUpjEiA3SiCbLNkrCmzEczmTdMWwWPltLH3YgzfZBNcMVAzqH9tes+7BIBJnzrdvAteWPDJGgcRvPpOkvmLlToFCiRcqZ0IkYm1UqKIYOjp8WBtHnKj/S0SJZNhl9VYAnl3eZ4IVpE2uH0wezuUsK3GzIVsUZrSOajlPMMz1yOUdOTOZH7WJRvC/h114zm5PH//yQb5WxjQZDXi7dXpX5wOGoPTS6H59vIX+gy4SvsiqSIhOQeTcZuAojQYeHlP77C15aeDR3u0mBWZ29FQYGdXxMwruQadZJQ7sLNQQ+YghB1nZq3r4esbm5rjF/TFGKNrIjoTYBgIoEGOiNnwSUMedt/YU9R/dQMo/HAKWsXUI8tABjZwAiaip9bcDis0bcev7lRHjiwwzMsEeHqDsKmyOUFQQMKrxH9uvsPT1RTWF3CaoDJXZClI9H6FgDuj4CCV0h6mLdjVfhH0CHbOpFh/4wcNu8VNWRChiZOe1BkjI900/cNVwqJiISnRd08iIRrZVLVWTINt/uqsR5SdeL0fxdmB6BbuUdyWwtK5L3j5e0NYei8ufr2XM6q+sSAahUNzhpNUakmJw2wCzORQwjvellZm4Acg2ZbnnKZOqq6AcGVenGck9DUfyAic0J1b43lhjyvvqpfZ6uf7EG0uOuhcrZwRNkL9ZBvb9OsFd9NoDYuKZwBv/1dbx0RdXtz6Z45IF9gtFxY1IaZRCC1Z1/3RpdLgwtjeFeotJv7N/aVSgqT5P2t2QwaFotVfDPNB6Io5CYjqHFEseQ1xmU4bqdX1dIrC3GXdTh3zLKSbu4MmDkluQ=="},{"id":"7ed0042c-9ec0-43b4-a5fd-2e4537db9eb9","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Mobile Application","description":"mobile-application","prompt":"Create comprehensive mobile application documentation for ApplyGuard PH's Capacitor-based mobile app. Document the cross-platform compatibility setup, native feature access, and mobile-specific optimizations. Explain the service worker implementation for offline functionality, push notifications, and background processing. Detail mobile UI adaptations, touch interactions, and device capability detection. Include build processes for iOS and Android, signing requirements, and app store deployment procedures. Address mobile-specific debugging, testing strategies, and performance considerations.","order":10,"progress_status":"completed","dependent_files":"capacitor.config.ts,src/mobile.js,mobile/README.md,public/sw.js","gmt_create":"2026-07-23T01:21:36.3297905+08:00","gmt_modified":"2026-07-23T01:47:54.7444572+08:00","raw_data":"WikiEncrypted:on0Ub2n3T72LCTbWaTpZiuIgXy2jc3EOsg+qkQRdz1vzkXshv89MLlGOJNJeTbmU8PTCRqFTSsGbA7U9aZ/MJk7L9fJKWNZ/y6quGotrpMfhA9RjidXD8eQ2HHqS1LCFZLQk8LXKy9iQOzwTOrfecXaaMV4SBo0LqlZJZ6o5hgiw3jmp4jPger3G6PzjOo7GgNtaT1BnZun0jq2cgbnRENcY7ANHMFnu0AuOsy3kWGUcpFf8it5GWaD+p6SEjbf+fG1hNeeBxWWhsbE3wawq4QZp55gTt1IloJrwPX53xL7HS1bmbBafMRx8rCbATspVMLCFih6EahMovKitTBS2IxdKzQWj0lOD8+FO+j1oIhbYVxurrWzBdqkdbLaqQ1YLaxCu31oROfdofiwNs0RTtatSZW9xHRa/40jMgfDGHuuNh1ijoWCcOgAMSOZYPum86chNLgNLeTr+EA21dnEhTAvFyLoybt0hetfEjYGqqbJ2Ia5GqphlJ1ngaTBEw92Tuo3aPQeUwEZLBB0seZRwyZC66cEUXCGhF4HVN4fM3WrCVMB7vKuXRG+1nvRydFkjVOq3lCCWyKS3HV5vwwWaupnjNRWFxo1HaLirrjJKyn3RW6OVMypdjptt773XU4VOGOtiL2mS4or+NyQ9i4C4wdF4GFfrkfndhKppcJcva/xua/oHlkPUEH+T+EY6vbrFHAEcZ4SH9toKmpq4Cdf9hF3u8ZI0mmQxFLdzsSYpmRLqTfI9P/O4YrAmJMs5Sec2LPXwtc6XeMsnfs/0m0pFCVAO0uI46QMYPY5Wu6VuXr+Brgm5x/dRvji96uoCsLA5tDU8Ap6imEu174JHSHCVGMtpcCoxEiH2AvFcWVqHPghrmh2fd5C2DnBArRSds8bPPttJ1d0VvUzXtIEvonuCbIpGYgFvW61nsFeoipz/h0zHHjhA0uHgQ6AM7lKDb3zEEbAU74yICNpGzF5IYEKgBbNozmLF0cOHZ5q2+jUCzpF+vl4bxzHiwHpFARqn31kryllg8NsvY6V0Rp/OxTEobXpmjc1O0glJVKl9p/T5KNhRYqiuh5AhbLqW3RrdZOxsCikJmloCjwjTyrxR27F+zSHkCuAa5iHuSAc+a4056rwVuBLcrrNWSND8pszVjHDbV2+2uB07i0/L2WGJGPGEUcY/nf2TwIE5DlCrXn8f2bPqDI8hbdeaXnJ/+B5SGk9YCsAiOZBuSdx43+CUhwTozAAO+iQa8kpK9JCCAM4W4JlF36+2MdyrLT881ot4vi3Qhr/gAp9YL5bkXxsyjNP13+Tb4+eU6RpiKKNzrw3Lcdv6I6sHguT4upI1hP/jE5UF"},{"id":"c870be03-f946-4159-9251-65e9a33f166c","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"API Reference","description":"api-reference","prompt":"Create comprehensive API reference documentation for ApplyGuard PH's backend services. Document all Supabase Edge Function endpoints including request/response schemas, authentication requirements, and error codes. Detail webhook interfaces for payment processors with payload formats, signature verification, and retry mechanisms. Include WebSocket APIs for real-time features, message formats, and connection handling. Document rate limiting, security headers, and versioning strategies. Provide client implementation examples, SDK usage patterns, and troubleshooting guides for common integration issues.","order":11,"progress_status":"completed","dependent_files":"supabase/functions/ai-proxy/index.ts,supabase/functions/create-checkout/index.ts,supabase/functions/paymongo-webhook/index.ts,supabase/functions/capture-paypal-order/index.ts","gmt_create":"2026-07-23T01:21:36.3297905+08:00","gmt_modified":"2026-07-23T01:47:54.0731978+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg+WPNa2UHH7yP2PPjE4/OPlAbu3AvGLNlwH2YbJEsK2ZFah4wHB5r1ikrL2gZxnF1LQq2iSHn5KSg/g7ZooEpvAciiyCe3BF46NNNF6aeLbBhJjePirHCJDxAMUIltTPlcddsQeewMPswVhP8ahTfA9dBuNjvSJHIl9NG39ri0NLLZpd9353njsuyU2oqDjKSs+kBsD5evRJ/QyJDk8okiAjDBCtOfF+hzCjgaTmClH1RoUiPGX7MKRJBFG7W3RmtP13QUjasA/PQF0DriX1bPx2QexBfMB5evBtW2/Xzc9cp1iWsQfnwMOCR9Vc2QK0UVKoafSHzothNa1I6EVoR5q2GxBDAIac+TBXk0dvV+ZcKe8SdZhNuXPFMzKr2nksJ7T8+ogFFX+nXzBbPV0tY8AFO77zECvMfo3K/oYx0pMOmMImg/YCruor4nwSJuP4ygIMbkNI2N3jHGCzFqdVTxGDue12HguYVJrVd2yl8UPKw3Zldf5fkVW32Dgwm15StWwmm8QMqSvkeZpFCI+nX62sBaCWhxE2Hrfoet8925JPkkcPh5g+zWs5DV5axZMyXOpKyo4ceI9UhxRWzykHBLwvdWq+M8r4qL5pSVAYoI7yjSbu0hcl5YBmCvqYOEGMO+1SF2VWd9Rc5m8kIQIaTJjKKtiZ9XYiZyY9dnQr1+HVOrnmm/+t7ZUWc8LpWbRiuQMfyQqI+j9Hy/vNmptNCnWeFMhho47ICWOY6nsNR2pBvVQ9YIJdXOZmzmWs58zjHZEeCsdjdXGUEbNV4kClegYus/mixHJidITcKSGIVc5VOFsDyVZ97GJAT48cQgAkmwuh8VWkXVrgepRoZjoPKelV939ZYkER9/enGYLZuLfQIBI3bBjW9hZJM+ZEb62VpWz1HinAEAvIeIpyUA+FHvjIrvM7M2rE6MxdVdFj1MpJYkyOzqwFj67vTbu8MFsQ8XEx0ku9NgisBcvVFRgHle5X1xIoJaTApmLG922AtZia26dj+ewMdWw7YqSAebTycwgNPBO1DSB1JC5Nj+4gtdpCQp6GIf556pDYQ/p3P/gf9dj85CWH/uWwnmm5XuAsJK+0CiRN/MmCQ6d2zeqZm1NknpM758Q9u70zXm0p8GhmjQ507BVwC+sj9w4hzJ/P6b81K30XG5MYwmGdJ45uAssMJ2h+MSL0syWw/l7UajrdRnF1+Y9o64wPyyClXflHZo6lmSEUTWNWL4pk7l8wPG8+YhuZROfFqtWIWdsDL703HSQf3HTJkQw/R/nlGGfoeBZSXQ61TsRljX9NcQWXVDZ7xBfnYYFZA0cp3BkWU1o6Hn9/hs2f6LuTVUAIHlsyq4gJQOMqONg32CyToqrg4Sxb0l2Zy83Y2bNlvlZQ3G5kwOaD4xzUWA1DvszSL9IcsxIkxxjpJOiCJBJ2RWGdSfcaqJvnmxoADLHr7JigS0Qwl2ZBTKhKdG7hYmmGnzJxIA=="},{"id":"071bfed4-c831-4891-9c40-5690a29fc726","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Testing Strategy","description":"testing-strategy","prompt":"Create comprehensive testing strategy documentation for ApplyGuard PH. Document the unit testing approach for business logic, component testing patterns, and integration testing for external services. Explain test organization, mocking strategies for third-party APIs, and continuous integration setup. Detail performance testing, load testing, and end-to-end testing procedures. Include testing best practices, code coverage requirements, and debugging techniques for failing tests. Document testing tools configuration and test data management strategies.","order":12,"progress_status":"completed","dependent_files":"src/lib/csv.test.js,src/lib/entitlement.test.js,src/lib/followups.test.js,src/lib/sync.test.js,supabase/functions/_shared/paypal.test.ts","gmt_create":"2026-07-23T01:21:36.3303117+08:00","gmt_modified":"2026-07-23T01:48:09.5148755+08:00","raw_data":"WikiEncrypted:a51tw9+B5Xez88YuZqi4cPV0J1CJauHTZselAZQ9sG40Lb0MosJIfbxZqj+gJA5m8musMdI2GJsw80+O72ORSYxiQrmIl/30jqbWAHjjPwEm5rSJQhk8HcijAcz+iAYPH4Z6Z8jtmYAjXZzfK4vK4B8IGM0E2s1FDSZxC9KNUfnj2bP67lIiVu7TSLkshBnaMvworT99DnR+3e8mo6o1QUq2SOHHm2yPvIBnSc2G4syEpZhtMVoW39CHi6nuD+mH5vWENSqyQURpUWS92AI9dteTBIZLrFpAT3Y5fGppl91N/GASHFFfA3v64/Ji7gg3iEwjXDKKqOvsRql2mox7TgaKUzFyivqm0LL61BMDBZKsh880Rp95O0qi/rze5DCMCCnQ0IJROgIKUC8aT6uAvY95Mt+Mz5rhsrwajnNDhjXpJoDIcu68NwpwdTPTfYY/O9U/fyPgnH9FXQ+25SnyevGpoKJ3DQkyueRt6lFVTDJ1EXw1tjsDHUZFa1QYrd0fJoVlo8BzKXs8pAz59rcYZHi7mnlqPMsG+7yptsYPBsV5AwfSfIJb7PMDyt8WIkJqFCyQ6VTNO+jIqbBvsXFd/OWHGYgwBEYSYCrP3S7pgz3Z4bl2U3BpA0iqTq77699hqvBGR8u50MpNOOKNahH+K1Wgb5bsbNggWw6kXiTR/tszqVdlbhFEVwsN3ODt0U7eUqd1fIPwZwVIytZhyyGcIw3r3g5w19GKZkuOLQxsIDpzsxrIkd9x1GRiAfLAacv18BMpd0mvo21/xQnAEDpo/Br8DrzahmhQUCMQrjv7+qkdjx12d5gvjSGaCK7LlO5ljdPWUHqtuI0+b/wrODwUsQCLGaV+YlHLqKgB/KFwdNiB87jJrZcY7/pGoDLGaQ0enzgW+aMKFL6NlwFT/LyGV4XysLs6hbvgN1FAPhvrdzeUpY8HfTs/22mDjHFXsk67rzby5hExgVYWe0oe12Gnz9ek05eQXD5yOTtwzcvMS/GOzpl/8jrLFne9lhzMotXcPd/vd4zcRobP2r5EeUahf+sGnmX3EZVPU9Qs+SHC7ntA9orWHnQWxrp9CBAooYW9xvb3SpV0lA2K9pQyVXCBrvRyXxELWEXRUYpDGXsKYCdOR8BHvRg6eCsDsMcHYD6pS8XMygge2xl+0mK4rDepThdeoKnsG89uNwDlCgxvYADAv6DFA/jMRm3mbnjdm1Mft0BeeHayH+ThOQEC8BfVk4zF/4x7AKNEzwRIGrdx1e3TcNhHuXzSZivqrRk+t2v/DQMLkuWZ9GFQ2bHozQghrt/Oh4WNU+XKo4UL5ullL74p67e7UqMawxqXumD3iANp3AypVi285cRxR0t/wiUaSLvxaMHTd1WE482ml2NCmHC2pA4EM3BZ1TC0OAu4YfW7"},{"id":"e20612b4-193b-47a4-b22c-9257ae93911a","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Deployment \u0026 DevOps","description":"deployment-devops","prompt":"Create comprehensive deployment and DevOps documentation for ApplyGuard PH. Document multi-platform deployment strategies for Netlify and Vercel, CI/CD pipeline configuration, and automated testing workflows. Explain environment variable management, secret handling, and configuration strategies across different environments. Detail monitoring setup, logging strategies, and error tracking implementation. Include rollback procedures, backup strategies, and disaster recovery plans. Document performance monitoring, alerting thresholds, and maintenance procedures.","order":13,"progress_status":"completed","dependent_files":"netlify.toml,vercel.json,.github/workflows/supabase.yml,package.json","gmt_create":"2026-07-23T01:21:36.3308505+08:00","gmt_modified":"2026-07-23T01:48:40.1533975+08:00","raw_data":"WikiEncrypted:0IKfLNOWe9mZfG1jVts3w0O9CfpuH1LS2rMZ8iFleEiuvaH36vfF0SkSRo0SCc1dXQyX2BEDphkgiEQwm7yEIkFMK4+EmwXOmMKIl26mC8/CJfrIWi/Dqp0Gjx9u/IE5ZfZh01Gt2sQphf5UhjLieLverw5L0iltERwvuALJtdsrVNLeO4dQtpTqTX0H+00+tEqsFjFC7HYCjLhfb7/aPoDwMZGMbsB4FGZpzgLymJDEblhQ8CxDRUL6rHMS9Wgtn/E6nxt5gS0j58QWWqLjegmR3YnOru1/Qe/hpEG9tUmf06pN6qMvMs1LfNTGwkPkgC1RmfrjY4XdbeorzTpXpHuGCMjBkbjsu27MAjcOLT5dgPB8fp7zpD6PBEepHan5VJkPkfRyVPTyEzgXcuIQpAGDfLYeTgKtKz50e80PxoK3EjchEeEKt71GCdM/y17M90ah02V2z6U7YvGkWBInQA7giJoRf/9daQMK/aSCrEu41J6dkLDl20iSQ5Nr4y523NhlDgQlmnWmlbrmCvyDea3p7Xbu7jr7x5ODXTSasqAPBlFfVZcTqwvlj2Q0NSlr6MfQinSD350oeAWhP9FAWZbBLFxySBmqisfX47VCw/9hyXSG5enfFsISZD62h/v8/qlUV/whPswUa7T3HWvZA0c47Fi4+VtmrQLm2nxQEw4Z0YW5GxyEoZ51UgOEW/bohKHZudAA5L42agRNGI2AfqaJYm8SGAlb5CjSIdH6zt1e47JPIr1b6+9ofrGBd9pNj2LZ6oA87+oauuHH1FZqL7vVSVKIpqDTwM8NNPIZy71vPh+L77bljzp3cbQfnKh1Z1i9Q6o7HSODnnBL9L5H1135x2/SeDg5ric1PdTrxfGCY526JEJS3faYV+kD/Yj90hzb0KknRef4xsi3LYcBcCrTVcHObxWxmnLSgc3naaL6lpYvCOYy0639WgShb0uZFpewLdwyC6YVlK48mkbEdqv2SplelKls4ZYRnM34GtY8uO661G/h/TL/mb5TCbNhYgPI+M+KbsDJ22Qhv7EsnOcYg5Z/8zAz59ztbVHuQgOAmnSf/YwVuIMAe1Hn++1s0SjVSjlBfG2OBxphdPVvbD5NzjRv0SgUd+5HetUxfSVk1f0Sy+xij15uYBYZKdocTsFXRV1cqkHe5+5yYZiU8qkNYnHBGHAEP464ZvLQsrqzm/jihyJqB5rO8LENCsti+ChJcRW30vaBHbG/gFWIN2+4U1yEdXkRWAUetxVrrSVpsJ+0v5Teum96toKFdDUwPXA8maxjnswYCUHsCxIiQQ=="},{"id":"edc4a5d1-b7ae-4062-8673-f2bfd4864bf0","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"Developer Guidelines","description":"developer-guidelines","prompt":"Create comprehensive developer guidelines for ApplyGuard PH contribution and development. Document code standards, ESLint configuration, Prettier formatting rules, and Git workflow procedures. Explain the pull request process, code review standards, and issue reporting guidelines. Detail debugging techniques, profiling tools, and performance optimization strategies. Include common troubleshooting scenarios, known limitations, and extension points for customization. Document the development environment setup, dependency management, and release procedures.","order":14,"progress_status":"completed","dependent_files":"package.json,.gitignore,docs/HANDOFF_QWEN_MAX.md","gmt_create":"2026-07-23T01:21:36.3308505+08:00","gmt_modified":"2026-07-23T01:49:07.3007064+08:00","raw_data":"WikiEncrypted:F3QgleoEfoy16cQggYe9C8Y3WUexfP1QsubA1ikdjGYsGJhTiM+55fzsvsPR3zOOXd9moVnTxcIKCHQYX40fLmwV1+btZKvsRi9GxcVgGiSQacCk+39Xi2Efvd7QidHDVwHIupO4SyNaIgVt85ZuDIKqrLVowzRXkzN2Mb9xYFp9JkKEdnf4Qm+8czXT78ujq+jR2f5ogY8o4xyi6uDNn1E+FBU+EZyu7z4LkHDGYv3G5s/JCKoIA3RB3Exxj3jsvnywjx4E8wF7lmAE5esCyKoL8omlT7M7fIeQJ0soyCFNO9s/cIfCaO+ceOyriKa6UsRzdIj1R0JKYfyOf44h+XKxjAvhW8iz28WifYHIIM1XNtFx1VoYj8/pe6CklehEdjHbwoHMucT/4jfJeiz1u63mABumhFqT88vlXYEJ7d0mS3Em4cYrU5/5VgvgSmHsnoylHSNR9gwgAAeDA5jSPama9aOM4vEMgrB6PFm4dbFokD79BNdHpR5eKPBo9XTOT7eLBRfyCHDIJUBswQn8ecEjNnxY78e5T946MciY/fqrxmvpEsXTjOvOas1fYUVbGgnT5UokKPHwb3e+b5+QgvpxeNcvELifMcmfIxjOAWZGfYpcCwYzU44i9TXy9l4R6ns0utNh9C4kEBU5nqRu2S8yWZslhvUnys9DXKjbDXVMI/zrKFTkla264Z7k7BE66J8JHbmnmS4VFveAtxHgwppOdm7XmIREeIoIQJ4mY5p7Xblo9XcjZ7uRry0ZxKVI261q5r9NKai3G60lPwFOr8aIjSuvRJ3XeyqkF8N3wz9NsXUzFCdq2hhtz1DSUqQFzL4fD9yiH/pIwoajN07jQIvKP8gGflBMcinM/g7pR/DoA0vNPQmns8Ly0uTyhIKCkKoLRoB40DDIRePT7B8t47cyu+hWVxmIKJnWExZ9KyqvzgSeO43YuSSnO2NjveJAiQU82YiHVKb4SpwLGgGfX48WHcAx4LmPPE/0XA7MeutPnjXfDPXRU+cLY3dBVs4hosldATFx9MbnlKDlY5GkBeHco8gAM7PEV3OWEL0Azi1CdEdR/Pcn2z3XpTl2kPmcrsw/zoor3svH2PYfuBPP6A+wF9ADr/1kBHfvxeipit/uwrTzbAm/atlOd4QjlSbF46cvh5EKudBsqsZB/hCRSX+C4wae89fFDDPYnee+2Y0htshu18b/dvnu0dbJJC8QTZWYMo16INnjltwtFCP1EcwrbabfFtzyRPbnlBb6re/vShkKU238w3xtZP9U4LpP"}],"wiki_items":[{"catalog_id":"b875171e-89a3-4da0-8593-431fa7182cfd","title":"Getting Started","description":"getting-started","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"168f5852-cf02-419e-955b-2537da680dfb","gmt_create":"2026-07-23T01:23:30.5396626+08:00","gmt_modified":"2026-07-23T01:23:30.5470999+08:00"},{"catalog_id":"66e799e0-8dd6-4668-ac43-a4bd7c42a5eb","title":"Payment Processors","description":"payment-processors","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"7c87d231-fa5a-4751-9cfd-0722a0e08673","gmt_create":"2026-07-23T01:23:39.7421697+08:00","gmt_modified":"2026-07-23T01:23:39.7502584+08:00"},{"catalog_id":"396a3cd4-40ed-493e-a4e0-cb04956136cf","title":"Authentication System","description":"authentication-system","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6f43f2ce-211e-4561-9ce4-403e8924276a","gmt_create":"2026-07-23T01:23:58.3622615+08:00","gmt_modified":"2026-07-23T01:23:58.3752403+08:00"},{"catalog_id":"45127b67-19f5-42b0-b44e-63fd3d377aae","title":"Edge Functions","description":"edge-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"cb931b0f-494b-4342-b2de-d3455bbacbca","gmt_create":"2026-07-23T01:24:05.7375096+08:00","gmt_modified":"2026-07-23T01:24:05.7482886+08:00"},{"catalog_id":"9ebcd167-847f-41f2-972e-edf32fcd8d66","title":"Capacitor Setup \u0026 Configuration","description":"capacitor-setup","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fcfd88e6-c729-4c23-939c-7eb01e39609c","gmt_create":"2026-07-23T01:24:28.1928918+08:00","gmt_modified":"2026-07-23T01:24:28.1987776+08:00"},{"catalog_id":"aad58f1e-81da-47d2-9000-d1e4cd8b660e","title":"Supabase Edge Functions","description":"edge-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"130a9db9-c3b8-4d3e-9fa3-2f991a250ca8","gmt_create":"2026-07-23T01:24:43.430144+08:00","gmt_modified":"2026-07-23T01:24:43.4376385+08:00"},{"catalog_id":"531c9699-6862-444f-8f72-71e9b8983826","title":"AI Interview Preparation","description":"ai-interview-preparation","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"dbd0ef0b-894a-472f-bfec-f903ddd1e40d","gmt_create":"2026-07-23T01:24:49.2403815+08:00","gmt_modified":"2026-07-23T01:24:49.2469016+08:00"},{"catalog_id":"15e41105-5f69-496c-a0c6-d162881bc0aa","title":"State Management","description":"state-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"7c8e9f5c-fa29-439d-9861-a403ccd46307","gmt_create":"2026-07-23T01:24:54.227078+08:00","gmt_modified":"2026-07-23T01:24:54.2320965+08:00"},{"catalog_id":"bea14602-7013-4ae9-a2ec-8f0c2eb62a02","title":"Frontend Architecture","description":"frontend-architecture","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ab8afc85-2c75-408c-ac12-6083bde9eb67","gmt_create":"2026-07-23T01:25:17.2188449+08:00","gmt_modified":"2026-07-23T01:25:17.2335488+08:00"},{"catalog_id":"8f93da33-291b-4b8e-a6c6-7ec71ff6e718","title":"Cloud Synchronization","description":"cloud-sync","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"a1c38a4d-d97f-4946-8afc-cd684338bf82","gmt_create":"2026-07-23T01:25:24.9187913+08:00","gmt_modified":"2026-07-23T01:25:24.9252581+08:00"},{"catalog_id":"807ef1ee-e7d0-4485-9b75-741a4a80cfab","title":"Scoring \u0026 Evaluation System","description":"scoring-algorithms","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"650d90b2-7f26-47a0-b1fc-a57f928538f3","gmt_create":"2026-07-23T01:25:52.1279909+08:00","gmt_modified":"2026-07-23T01:25:52.1428088+08:00"},{"catalog_id":"bb8fd4c4-918c-4926-b9b9-cccc592579df","title":"Subscription Lifecycle Management","description":"subscription-lifecycle","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"813659f7-1f44-4777-8b8b-711d0a7c4034","gmt_create":"2026-07-23T01:26:09.1991868+08:00","gmt_modified":"2026-07-23T01:26:09.2148066+08:00"},{"catalog_id":"de0447f1-2939-4ffc-a07b-9780fb389421","title":"Database Schema","description":"database-schema","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"a2664f5c-317d-48ec-aaa2-3721c4918e94","gmt_create":"2026-07-23T01:26:14.3474165+08:00","gmt_modified":"2026-07-23T02:10:32.1862955+08:00"},{"catalog_id":"613875e5-a4e6-4b1a-9741-8fa7cdd2d1c4","title":"User Accounts \u0026 Profiles","description":"user-accounts","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"7a8dffc7-fba2-4c9c-9701-587d24e2ebfa","gmt_create":"2026-07-23T01:26:39.3099457+08:00","gmt_modified":"2026-07-23T01:26:39.3212429+08:00"},{"catalog_id":"5c9da896-ab28-400a-9241-b2057092c570","title":"Mobile Development Workflow","description":"mobile-development","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"7f471ec6-418d-4e9e-8a7b-5ff31e821e2e","gmt_create":"2026-07-23T01:26:40.8219016+08:00","gmt_modified":"2026-07-23T01:26:40.8316177+08:00"},{"catalog_id":"cda46bd6-f210-4ff9-826a-1df0b3cd252a","title":"Payment Webhook APIs","description":"webhook-apis","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"174da3e3-e8c6-4329-8b6d-114067e34196","gmt_create":"2026-07-23T01:26:51.7417194+08:00","gmt_modified":"2026-07-23T01:26:51.7477313+08:00"},{"catalog_id":"e847f4d2-fffd-4700-bb10-98246cdd7d76","title":"Offer Management \u0026 Comparison","description":"offer-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"5e3f5cc1-ce41-4886-b464-457832be2447","gmt_create":"2026-07-23T01:27:08.2772426+08:00","gmt_modified":"2026-07-23T01:27:08.2874105+08:00"},{"catalog_id":"7fbc634a-0afd-4826-b865-d8e1bb486b88","title":"Styling \u0026 Theming","description":"styling-theming","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"dcff2cd0-d56f-4560-ab42-0579c61b6fe0","gmt_create":"2026-07-23T01:27:20.8319887+08:00","gmt_modified":"2026-07-23T01:27:20.8384944+08:00"},{"catalog_id":"b9cbb862-07a3-4429-bb2b-1691865594e0","title":"Backend Services","description":"backend-services","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6e8a2261-a4a1-469b-b0cd-ded934fb2502","gmt_create":"2026-07-23T01:27:45.2663789+08:00","gmt_modified":"2026-07-23T01:27:45.2753565+08:00"},{"catalog_id":"f8486f05-0d3a-48e2-b0e6-1567cc797fd2","title":"Import \u0026 Export","description":"import-export","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"68e10916-bfa4-41d8-b77d-4e84ddc2ccc8","gmt_create":"2026-07-23T01:27:56.4978366+08:00","gmt_modified":"2026-07-23T01:27:56.5010546+08:00"},{"catalog_id":"fd421ee8-b963-4821-b1d2-fbfc0ed64396","title":"Follow-up Management System","description":"follow-up-automation","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"624e3361-fed5-4347-aedc-d8dc7126f31a","gmt_create":"2026-07-23T01:27:57.4546827+08:00","gmt_modified":"2026-07-23T01:27:57.4594701+08:00"},{"catalog_id":"9488f56c-fc6b-4c83-9ebf-4f35ef97e05e","title":"Pricing \u0026 Plan Configuration","description":"pricing-configuration","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6101dd0e-18d5-4021-8513-d52c228e488a","gmt_create":"2026-07-23T01:28:24.755513+08:00","gmt_modified":"2026-07-23T01:28:24.7587672+08:00"},{"catalog_id":"abeb2b5d-488a-45f3-85e1-d7f8f2b83cba","title":"Shared Utilities Library","description":"shared-utilities","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"40ab90f4-c71a-4ccc-bd4a-ae19a9de37a3","gmt_create":"2026-07-23T01:28:42.2816449+08:00","gmt_modified":"2026-07-23T01:28:42.2864083+08:00"},{"catalog_id":"5825996b-9757-44f7-9ee7-76b1811047e2","title":"Entitlements \u0026 Access Control","description":"entitlements-access-control","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fc1625f7-98fe-4301-8072-59f864f7271c","gmt_create":"2026-07-23T01:28:45.0590927+08:00","gmt_modified":"2026-07-23T01:28:45.0646977+08:00"},{"catalog_id":"008d7970-ad47-4dfe-acec-79b3b4ba24b5","title":"Native Platform Integrations","description":"native-integrations","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"f7e89e4b-a8b0-4160-afb8-c76e6d7c38d3","gmt_create":"2026-07-23T01:28:56.6993389+08:00","gmt_modified":"2026-07-23T01:28:56.7022788+08:00"},{"catalog_id":"aa03d6fe-9ab5-4b24-ac71-ec108a0ee51c","title":"Real-time Communication APIs","description":"realtime-apis","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"1c5419db-05c6-40c0-acf3-b6c1ce5b11f8","gmt_create":"2026-07-23T01:29:13.673759+08:00","gmt_modified":"2026-07-23T01:29:13.6811144+08:00"},{"catalog_id":"fe574ffc-5503-45f6-8775-410a5a8076ec","title":"PWA \u0026 Offline Support","description":"pwa-offline-support","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"c715b8d2-8070-47aa-bfcf-3dee1f30f87c","gmt_create":"2026-07-23T01:29:23.3304407+08:00","gmt_modified":"2026-07-23T01:29:23.3340099+08:00"},{"catalog_id":"2bb031d6-69e4-4dc3-8dca-10b17783fa6e","title":"Resume Scanner \u0026 Analysis","description":"resume-scanner","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"c5bab8e6-829c-4015-9586-39d30bfb2302","gmt_create":"2026-07-23T01:29:28.9004582+08:00","gmt_modified":"2026-07-23T01:29:28.9053271+08:00"},{"catalog_id":"a12988aa-3acb-48ff-b3d6-4dd559e17ac5","title":"Data Flow Architecture","description":"data-flow-architecture","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ee5ed5e8-fb0a-4d24-920b-9e658a00c305","gmt_create":"2026-07-23T01:29:40.1559497+08:00","gmt_modified":"2026-07-23T01:29:40.1617783+08:00"},{"catalog_id":"59876848-dcd2-44c8-aedc-1c54b8d48e3d","title":"Statistics \u0026 Analytics Engine","description":"statistics-analytics","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"85253f3a-b62f-4492-a8e2-95f09883b4ee","gmt_create":"2026-07-23T01:29:52.6012598+08:00","gmt_modified":"2026-07-23T01:29:52.6072374+08:00"},{"catalog_id":"9b3a12d8-298f-4abf-8642-26f50ae4b972","title":"Data Sharing \u0026 Clipboard","description":"data-sharing","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"0e6e42c5-2f5b-4cba-ae20-091168e66fa6","gmt_create":"2026-07-23T01:30:08.5267691+08:00","gmt_modified":"2026-07-23T01:30:08.5331128+08:00"},{"catalog_id":"85932b14-1605-4c35-8a54-ec2a3a78e484","title":"App Build \u0026 Deployment","description":"app-deployment","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"81caaa05-32a8-49e3-8b93-cce40beed2dd","gmt_create":"2026-07-23T01:30:19.8429971+08:00","gmt_modified":"2026-07-23T01:30:19.8463418+08:00"},{"catalog_id":"e5770f9f-227c-4060-97eb-f9ed467c718c","title":"Webhook Processing \u0026 Event Handling","description":"webhook-handling","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"7e04e1fe-9dc6-4f1a-90c4-50032f8042f2","gmt_create":"2026-07-23T01:30:31.4741256+08:00","gmt_modified":"2026-07-23T01:30:31.4860323+08:00"},{"catalog_id":"9a77d4ee-ff32-47a2-b746-fc508706f196","title":"Integration Patterns","description":"integration-patterns","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"0ed0995a-fa23-445d-90cb-82e1b8b90368","gmt_create":"2026-07-23T01:30:51.2672135+08:00","gmt_modified":"2026-07-23T01:30:51.2778976+08:00"},{"catalog_id":"827f407f-f618-451b-bd83-484a188044ce","title":"Next Action Suggestion Engine","description":"next-action-suggestions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fd7c30f1-7245-4209-9df9-831da20bb681","gmt_create":"2026-07-23T01:31:10.3678768+08:00","gmt_modified":"2026-07-23T01:31:10.3821658+08:00"},{"catalog_id":"0916ae4a-5bb1-4518-8451-99f508885422","title":"Mock Interview Interface","description":"mock-interview-interface","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"cd5c2fbf-88fc-46fd-8efc-0f48452ea130","gmt_create":"2026-07-23T01:31:10.4736305+08:00","gmt_modified":"2026-07-23T01:31:10.4860627+08:00"},{"catalog_id":"6c29e642-e8d4-451c-b0ff-c6ef0b151c45","title":"Tracker Dashboard \u0026 Interface","description":"tracker-dashboard","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"d8071b4e-e992-45dd-b490-b0d1b589d98f","gmt_create":"2026-07-23T01:31:32.4815882+08:00","gmt_modified":"2026-07-23T01:31:32.4858525+08:00"},{"catalog_id":"2dd530f9-b2f2-4f38-8cfe-817746425a39","title":"Offer Input \u0026 Management","description":"offer-input-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"d03d56a8-3095-4f9b-9daf-d547a453325e","gmt_create":"2026-07-23T01:31:42.2721842+08:00","gmt_modified":"2026-07-23T01:31:42.2770462+08:00"},{"catalog_id":"714b137d-5a15-45ec-830a-e5788683db3f","title":"Context Store Architecture","description":"context-store","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"3917eb63-04bb-43da-bc8c-4e8a12a29740","gmt_create":"2026-07-23T01:31:46.091348+08:00","gmt_modified":"2026-07-23T01:31:46.0966534+08:00"},{"catalog_id":"ae6aa76c-b442-42b8-8ca1-b2688bab85b8","title":"Edge Functions","description":"edge-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"f6e358fe-f4b7-4af6-9dd2-fb0864c5e5dc","gmt_create":"2026-07-23T01:32:11.1310491+08:00","gmt_modified":"2026-07-23T01:32:11.1371858+08:00"},{"catalog_id":"1be16ede-7e29-4d0a-92a4-afc8e48d3725","title":"Layout Components","description":"layout-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"2cb527c6-096c-4f04-99ba-ca50b7f02c3f","gmt_create":"2026-07-23T01:32:16.3872014+08:00","gmt_modified":"2026-07-23T01:32:16.3934438+08:00"},{"catalog_id":"80cd19aa-ad84-4b1b-b83a-8a34a7c03774","title":"Component System","description":"component-system","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"5b3e8598-0e52-4020-9a4b-b82d9222f776","gmt_create":"2026-07-23T01:32:17.3773218+08:00","gmt_modified":"2026-07-23T01:32:17.382137+08:00"},{"catalog_id":"1896df7c-d615-4342-be7b-ec84ad9701c3","title":"Scoring Algorithms","description":"scoring-algorithms","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"873168ee-4954-463b-98f0-4bb67adaed30","gmt_create":"2026-07-23T01:32:48.9392361+08:00","gmt_modified":"2026-07-23T01:32:48.9462348+08:00"},{"catalog_id":"9a220833-59ad-4f85-b97a-3c86cb66f887","title":"AI Integration System","description":"ai-integration-system","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"d37f0e06-479e-4598-8fd6-0d546d548831","gmt_create":"2026-07-23T01:32:49.1111692+08:00","gmt_modified":"2026-07-23T01:32:49.1204222+08:00"},{"catalog_id":"3095f9d4-3ac4-4530-8202-b3489db7e21f","title":"PayMongo Integration","description":"paymongo-integration","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"4caca7e5-6697-4466-b167-68074d08c15a","gmt_create":"2026-07-23T01:32:55.2912068+08:00","gmt_modified":"2026-07-23T01:32:55.3003546+08:00"},{"catalog_id":"13f698e3-d6b3-4d3c-b622-6159b3f54a91","title":"AI Proxy Function","description":"ai-proxy-function","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"a04a71f4-3fbb-45d0-bfee-b10f9dce2e00","gmt_create":"2026-07-23T01:33:14.1657455+08:00","gmt_modified":"2026-07-23T01:33:14.1715631+08:00"},{"catalog_id":"e60a259a-fab3-49ad-b431-ab36230a765c","title":"PayMongo Webhook API","description":"paymongo-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"5d8be249-8b71-4a61-bf4a-efdfe2892d56","gmt_create":"2026-07-23T01:33:15.1240841+08:00","gmt_modified":"2026-07-23T01:33:15.1273011+08:00"},{"catalog_id":"36c95a35-68ff-4e50-9375-cde78d578892","title":"AI Proxy Service","description":"ai-proxy-function","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"811ea0a9-3c6e-47f9-b1bd-9d50274b2539","gmt_create":"2026-07-23T01:33:21.2764598+08:00","gmt_modified":"2026-07-23T01:33:21.2818296+08:00"},{"catalog_id":"45e8d4d0-3fb8-4a27-bc8f-7eeeb40b92cc","title":"AI Assistant \u0026 Coaching","description":"ai-assistant-coaching","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ec6cfe49-fe58-4421-a7ad-beb7c03f52bb","gmt_create":"2026-07-23T01:33:53.4533346+08:00","gmt_modified":"2026-07-23T01:33:53.458164+08:00"},{"catalog_id":"229b9044-125e-4b57-874f-0f47e928aa1e","title":"Application CRUD Operations","description":"application-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"06ce0d34-6e01-45ad-879e-b669d78b657f","gmt_create":"2026-07-23T01:33:54.0165098+08:00","gmt_modified":"2026-07-23T01:33:54.0239054+08:00"},{"catalog_id":"035167f9-ae3e-4f72-98de-c2208cbdc93e","title":"Comparison Tools \u0026 Matrix","description":"comparison-tools","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fec1de01-1e66-442a-a7db-a87e4af03a07","gmt_create":"2026-07-23T01:34:01.9822496+08:00","gmt_modified":"2026-07-23T01:34:01.9864218+08:00"},{"catalog_id":"01ffc783-a078-49f1-9560-ab6646dcfd20","title":"Custom Hooks Library","description":"custom-hooks","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"136a9e9e-9db5-414f-9884-abd9f32eec0d","gmt_create":"2026-07-23T01:34:21.8202624+08:00","gmt_modified":"2026-07-23T01:34:21.8237035+08:00"},{"catalog_id":"e8807cb2-64a1-472b-91d3-d56e1f9a3435","title":"Form Components","description":"form-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"0b3cf703-787d-4d5b-9b09-f6e8a99e8725","gmt_create":"2026-07-23T01:34:35.3173423+08:00","gmt_modified":"2026-07-23T01:34:35.3214756+08:00"},{"catalog_id":"851fabdf-9e04-4bef-bed2-56b6ba65941d","title":"State Management","description":"state-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"0f515cb7-b028-481b-b603-d4e31d90ae09","gmt_create":"2026-07-23T01:34:37.7559173+08:00","gmt_modified":"2026-07-23T01:34:37.7623306+08:00"},{"catalog_id":"550a161e-2590-4b89-9908-1f40dc9b5e66","title":"Shared Utilities Library","description":"shared-utilities","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"20d97977-822b-4d02-a223-9b9a9841082f","gmt_create":"2026-07-23T01:35:01.1965265+08:00","gmt_modified":"2026-07-23T01:35:01.2029688+08:00"},{"catalog_id":"c7fcbe37-a3ea-4e09-a6e3-e50d05951529","title":"Red Flag Detection System","description":"red-flag-detection","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"362396ff-4cd6-45c4-b111-571b54d1ff78","gmt_create":"2026-07-23T01:35:03.7821086+08:00","gmt_modified":"2026-07-23T01:35:03.7912471+08:00"},{"catalog_id":"40463b76-2f11-4b46-889f-ba610bbac190","title":"Tone Analysis Algorithms","description":"tone-analysis-algorithms","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"a264ffd0-6923-45e0-8ba7-15fd7c2ca396","gmt_create":"2026-07-23T01:35:12.2509699+08:00","gmt_modified":"2026-07-23T01:35:12.2606299+08:00"},{"catalog_id":"b905b7a7-7bd7-4340-aa8c-f7181b08b946","title":"PayPal Integration","description":"paypal-integration","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"1addd91a-7bb1-4d30-8890-34caadd3a86b","gmt_create":"2026-07-23T01:35:43.1474519+08:00","gmt_modified":"2026-07-23T02:10:29.6998487+08:00"},{"catalog_id":"ba28b066-6e73-4f39-b54c-612bae202098","title":"Billing \u0026 Payment Functions","description":"billing-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6804acac-8424-4b07-9c5c-39207d1635ce","gmt_create":"2026-07-23T01:35:48.7759783+08:00","gmt_modified":"2026-07-23T01:35:48.7817058+08:00"},{"catalog_id":"00c13ec1-dff1-49df-bfa4-0d18010f084f","title":"PayPal Webhook API","description":"paypal-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"1c30d26c-5caa-4062-95d8-dc554fd5785a","gmt_create":"2026-07-23T01:36:14.4019369+08:00","gmt_modified":"2026-07-23T01:36:14.4222546+08:00"},{"catalog_id":"8de1bf90-4b69-4f92-8d25-cf65d00831cf","title":"Tone Analysis \u0026 Response Evaluation","description":"tone-analysis-evaluation","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ec9b8bd3-1056-46f6-87b7-8e382a370348","gmt_create":"2026-07-23T01:36:18.5202553+08:00","gmt_modified":"2026-07-23T01:36:18.5254644+08:00"},{"catalog_id":"8c623eb0-3465-412a-9717-f8413bae5ca2","title":"Billing \u0026 Payment Functions","description":"billing-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"12d2ce47-ed9f-4d45-ad03-9d6817413345","gmt_create":"2026-07-23T01:36:40.5523383+08:00","gmt_modified":"2026-07-23T01:36:40.5598176+08:00"},{"catalog_id":"ef1d6364-60b2-4a20-8c57-32319bd3ef19","title":"Scoring Algorithms \u0026 Weighted Analysis","description":"scoring-algorithms","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"a5ca0136-be08-4f17-ba3f-662b8fb1112f","gmt_create":"2026-07-23T01:36:50.4713744+08:00","gmt_modified":"2026-07-23T01:36:50.486323+08:00"},{"catalog_id":"7da1925e-ce69-4e08-85b7-74f2aa2c5b88","title":"Status Tracking \u0026 Workflows","description":"status-tracking-system","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6d060bf1-4cfd-4a4a-8fb6-4b20b68bfd0e","gmt_create":"2026-07-23T01:36:52.1939487+08:00","gmt_modified":"2026-07-23T01:36:52.1987219+08:00"},{"catalog_id":"bb446a02-b60b-47a3-a03d-542679dfc768","title":"Local Storage \u0026 Persistence","description":"local-storage","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"52d624b9-5360-4bc1-87f6-0ecf5b83ba0e","gmt_create":"2026-07-23T01:37:11.318526+08:00","gmt_modified":"2026-07-23T01:37:11.323825+08:00"},{"catalog_id":"81dcf3b6-f857-40eb-b45d-b90b9d19d001","title":"Build \u0026 Development Configuration","description":"build-configuration","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"b1a30f64-960c-451e-ada7-ccff9eba95f6","gmt_create":"2026-07-23T01:37:17.2841619+08:00","gmt_modified":"2026-07-23T01:37:17.291047+08:00"},{"catalog_id":"061f0c40-a29d-44db-b39c-0a6dde56f826","title":"Display Components","description":"display-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"bd64e7d8-0cb1-4e28-8485-d2b67e758171","gmt_create":"2026-07-23T01:37:22.2883044+08:00","gmt_modified":"2026-07-23T01:37:22.2959249+08:00"},{"catalog_id":"bc2818a6-4a53-451f-9518-11a7d1a1685c","title":"Database Schema \u0026 Migrations","description":"database-schema","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"c5b58c7f-08d1-4545-8c9a-af114f1fc6ab","gmt_create":"2026-07-23T01:37:48.5495243+08:00","gmt_modified":"2026-07-23T01:37:48.5555501+08:00"},{"catalog_id":"8e09b78d-e5b2-453d-8bbb-2e3cfafb2f05","title":"Content Parsing Engine","description":"content-parsing-engine","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"12a298c9-3ac0-49b7-bac3-a8aceb5fd341","gmt_create":"2026-07-23T01:37:49.2924155+08:00","gmt_modified":"2026-07-23T01:37:49.2981804+08:00"},{"catalog_id":"cfd994ce-2142-4648-a724-dac2936a10a9","title":"PayPal Integration Functions","description":"paypal-integration","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"f71247d3-2375-42aa-bbc1-638c1887218d","gmt_create":"2026-07-23T01:38:06.879615+08:00","gmt_modified":"2026-07-23T01:38:06.8844968+08:00"},{"catalog_id":"bc5a4e4d-5060-4d74-8601-25ec04432b1d","title":"Data Export \u0026 Utilities","description":"data-export-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"2f0a73c2-9055-48fd-8b61-a08898ccd82c","gmt_create":"2026-07-23T01:38:24.6659124+08:00","gmt_modified":"2026-07-23T01:38:24.6705273+08:00"},{"catalog_id":"4f94ff87-144f-46aa-a17c-fcbf9da47b9a","title":"Follow-up Management System","description":"follow-up-automation","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"7a38bc59-3f8e-4a91-9b8d-ee3ca0e4eff7","gmt_create":"2026-07-23T01:38:25.9079421+08:00","gmt_modified":"2026-07-23T01:38:25.9131902+08:00"},{"catalog_id":"0b49f368-cf30-4b29-8d2c-35444cad28f5","title":"Red Flag Detection System","description":"red-flag-detection","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6b371647-77e3-4cc5-b571-d9a1a488cf4a","gmt_create":"2026-07-23T01:38:38.6467917+08:00","gmt_modified":"2026-07-23T01:38:38.653895+08:00"},{"catalog_id":"58173afd-65cf-45a1-bfa7-dbd35bfa98cc","title":"Feedback \u0026 Utility Components","description":"feedback-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fca2cf7c-9bb9-44cd-a6ff-ff332c848066","gmt_create":"2026-07-23T01:38:56.8048461+08:00","gmt_modified":"2026-07-23T01:38:56.8095225+08:00"},{"catalog_id":"1d923c0b-a057-460a-8a42-ada60b2dab7b","title":"Cloud Synchronization","description":"cloud-sync","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"8653bbaa-86a5-4a06-a72c-a2f1a1e740e9","gmt_create":"2026-07-23T01:39:02.79656+08:00","gmt_modified":"2026-07-23T01:39:02.8030229+08:00"},{"catalog_id":"6426aa08-8de3-4d15-a0bb-b4b8ee0c4d75","title":"Utility Functions","description":"utility-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"25141978-6cab-4672-afe0-db425d50cd9e","gmt_create":"2026-07-23T01:39:30.8883225+08:00","gmt_modified":"2026-07-23T01:39:30.8922867+08:00"},{"catalog_id":"0b725424-d2e1-4ded-98d6-7f9559db2877","title":"PayMongo Webhook Handler","description":"paymongo-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"055aedc6-d434-4810-b9ca-563cee8b6a89","gmt_create":"2026-07-23T01:39:31.31858+08:00","gmt_modified":"2026-07-23T01:39:31.3228145+08:00"},{"catalog_id":"103637cc-148a-4d2d-8b2d-f3a47935286b","title":"Analytics \u0026 Statistics","description":"analytics-statistics","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"c3dd5c76-9353-4573-a4cc-9d1b73474c77","gmt_create":"2026-07-23T01:39:36.0531047+08:00","gmt_modified":"2026-07-23T01:39:36.0598346+08:00"},{"catalog_id":"59e209b6-68c1-49be-abec-626bfe7cdc1d","title":"Layout Components","description":"layout-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"d93643a2-8666-47a6-95b9-2efe789c71c9","gmt_create":"2026-07-23T01:39:58.0065642+08:00","gmt_modified":"2026-07-23T01:39:58.0102192+08:00"},{"catalog_id":"45669aaa-6053-4fd6-8ec6-372d9b88b0ae","title":"Status Pipeline Management","description":"status-pipeline-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"8bda8974-4c19-4f3d-aa33-3a0f9401d50f","gmt_create":"2026-07-23T01:40:05.7296498+08:00","gmt_modified":"2026-07-23T01:40:05.7350372+08:00"},{"catalog_id":"9ccfbe19-1be4-45cf-9265-638ddc1b34e1","title":"Next Action Suggestions","description":"next-action-suggestions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"244a7635-aee7-4997-8bde-8650e0258fa2","gmt_create":"2026-07-23T01:40:22.4022615+08:00","gmt_modified":"2026-07-23T01:40:22.4086593+08:00"},{"catalog_id":"4485b7cc-5d93-4fb8-994e-c8c5ad2f3f95","title":"AI Proxy Function","description":"ai-proxy-function","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"bf7bcf00-6bc8-4011-856d-9599db635e61","gmt_create":"2026-07-23T01:40:45.4163526+08:00","gmt_modified":"2026-07-23T01:40:45.4201087+08:00"},{"catalog_id":"abd058c6-adc8-4d6f-a32a-b642bf97166b","title":"Checkout Creation Functions","description":"checkout-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ae7cb597-7377-4c4a-9ccf-7177a1297172","gmt_create":"2026-07-23T01:40:46.4575612+08:00","gmt_modified":"2026-07-23T01:40:46.4613685+08:00"},{"catalog_id":"fbd04a9a-1d7c-436c-838b-dcf4a2c76773","title":"Follow-up Automation","description":"follow-up-automation","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"e0adec41-36a7-4997-9d39-62ebd8e126bb","gmt_create":"2026-07-23T01:40:52.07363+08:00","gmt_modified":"2026-07-23T01:40:52.0784077+08:00"},{"catalog_id":"203e889f-a9f4-461e-8662-bf12c97bcb92","title":"Form Components","description":"form-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ad9531d9-601e-4dde-844f-6b1994675fd9","gmt_create":"2026-07-23T01:41:18.2394921+08:00","gmt_modified":"2026-07-23T01:41:18.2492371+08:00"},{"catalog_id":"c6e6b197-bdc6-4fc1-94a3-7830432a4abc","title":"PayMongo Webhook Handler","description":"paymongo-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"777ae6e8-f1f4-46da-9f7a-a9209d4fb4ae","gmt_create":"2026-07-23T01:41:19.4567892+08:00","gmt_modified":"2026-07-23T01:41:19.4628077+08:00"},{"catalog_id":"672fcca8-aa26-4601-b5cb-90009d3ba4a5","title":"Billing Webhook Handlers","description":"billing-webhooks","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"8fe13cfb-970c-4495-9237-a7c099313dc2","gmt_create":"2026-07-23T01:41:37.4761673+08:00","gmt_modified":"2026-07-23T01:41:37.4853049+08:00"},{"catalog_id":"0e0ca600-90d3-470e-af91-b0e36e3544e1","title":"Checkout \u0026 Subscription Management","description":"checkout-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"580b1cad-169f-492a-9808-b6e50a73bb17","gmt_create":"2026-07-23T01:41:56.5489634+08:00","gmt_modified":"2026-07-23T01:41:56.5537871+08:00"},{"catalog_id":"4fb1906e-2fd3-44f3-b2fb-85a358f4eb2e","title":"Display Components","description":"display-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"47d11b23-33b3-40a7-9ec6-e17143543335","gmt_create":"2026-07-23T01:42:03.9544969+08:00","gmt_modified":"2026-07-23T01:42:03.9593568+08:00"},{"catalog_id":"77d36a58-c65c-4218-b574-7b86b031d000","title":"PayPal Order Management","description":"paypal-order-functions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"c5c8e666-fb3e-4430-8e6f-2fde0f429319","gmt_create":"2026-07-23T01:42:31.1898768+08:00","gmt_modified":"2026-07-23T01:42:31.1965376+08:00"},{"catalog_id":"ee40670a-f27d-4dfc-bd60-c47ddedd85ef","title":"Utility Components","description":"utility-components","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"2dd63aa4-8560-409c-bf54-377ba4d036a4","gmt_create":"2026-07-23T01:42:38.1574283+08:00","gmt_modified":"2026-07-23T01:42:38.1611738+08:00"},{"catalog_id":"42596396-d320-4fed-9fa8-b285ff0708b2","title":"Data Export Utilities","description":"data-utilities","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fe8a23cd-6ffb-44f0-92bf-2ceb833275c7","gmt_create":"2026-07-23T01:42:38.9529587+08:00","gmt_modified":"2026-07-23T01:42:38.9596936+08:00"},{"catalog_id":"dcbda18a-c2a8-4b5e-bc54-cf01ba4d7a52","title":"Subscription Cancellation Service","description":"subscription-cancellation","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"babb38b4-3464-43f8-af32-4c89ce235e8a","gmt_create":"2026-07-23T01:43:15.770156+08:00","gmt_modified":"2026-07-23T01:43:15.7765837+08:00"},{"catalog_id":"dc6d0bd1-9d98-40ea-af1b-3bdbed88d863","title":"PayPal Webhook Handler","description":"paypal-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"2934e026-a0ec-46ed-84ea-c153dfd41808","gmt_create":"2026-07-23T01:43:19.5500239+08:00","gmt_modified":"2026-07-23T01:43:19.5557846+08:00"},{"catalog_id":"f4b74e1a-5e05-4fc2-a6cf-0a60fc33e506","title":"PayMongo Webhook Handler","description":"paymongo-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"1ca86cc8-2fe2-4d9f-996b-b04ec4cc7550","gmt_create":"2026-07-23T01:43:21.3966101+08:00","gmt_modified":"2026-07-23T01:43:21.4025657+08:00"},{"catalog_id":"a74e4570-cae3-46a7-b9c5-bfd9be09e8fb","title":"PayPal Order Capture Flow","description":"paypal-order-capture","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"a274eebc-f1f4-443b-80a3-1d7ee0148007","gmt_create":"2026-07-23T01:44:08.1394793+08:00","gmt_modified":"2026-07-23T01:44:08.1478597+08:00"},{"catalog_id":"c283d799-42c0-4098-a721-2485211f7ac5","title":"PayPal Webhook Handler","description":"paypal-webhook","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"6955aa54-5599-4834-87e3-cbb200ecefc7","gmt_create":"2026-07-23T01:44:22.7563261+08:00","gmt_modified":"2026-07-23T01:44:22.7609831+08:00"},{"catalog_id":"531def32-f496-4527-aa66-895ddc7ac7bc","title":"Frontend Architecture","description":"frontend-architecture","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"fb00839d-693c-4371-9a3f-30d6e9e87dd8","gmt_create":"2026-07-23T01:44:40.3462185+08:00","gmt_modified":"2026-07-23T01:44:40.3472777+08:00"},{"catalog_id":"564369b0-e95c-4c08-81ae-df1e1ba0bbb0","title":"Core Features","description":"core-features","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ef627730-70d8-4ff3-b3ff-d66e42000bcd","gmt_create":"2026-07-23T01:45:26.6333631+08:00","gmt_modified":"2026-07-23T01:45:26.644252+08:00"},{"catalog_id":"a62c01b7-2292-49d3-80b8-d7616a455c58","title":"Project Overview","description":"project-overview","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"4cdf4e51-c859-42d5-928d-18f7d1da7d14","gmt_create":"2026-07-23T01:45:39.6188884+08:00","gmt_modified":"2026-07-23T01:45:39.6328312+08:00"},{"catalog_id":"e57294a7-1441-49ee-a151-2cdd4a843bd4","title":"Architecture Overview","description":"architecture-overview","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"c5ca89d4-889e-4145-891c-29ea1334963e","gmt_create":"2026-07-23T01:45:43.2002468+08:00","gmt_modified":"2026-07-23T01:45:43.2102693+08:00"},{"catalog_id":"1968d404-384a-4a0b-82f7-a66bf82b925d","title":"Business Logic Layer","description":"business-logic","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ac5d7961-e755-48f5-9339-2773fe90d05c","gmt_create":"2026-07-23T01:46:05.2773555+08:00","gmt_modified":"2026-07-23T01:46:05.2843537+08:00"},{"catalog_id":"4c08a624-9311-45cb-a77c-0010b16eb5df","title":"Data Management","description":"data-management","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"552f3223-957c-45ce-9b5d-a407be3c0deb","gmt_create":"2026-07-23T01:46:35.169223+08:00","gmt_modified":"2026-07-23T01:46:35.1762361+08:00"},{"catalog_id":"6545bd99-a4a2-45bf-acee-bdb022c420ed","title":"Authentication \u0026 User Management","description":"authentication-users","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"f9776e57-edab-4bfd-85e3-6eb9b60a8150","gmt_create":"2026-07-23T01:46:53.5309462+08:00","gmt_modified":"2026-07-23T01:46:53.5386138+08:00"},{"catalog_id":"0ed40228-e6f9-4241-94eb-1ab69560f488","title":"Billing \u0026 Subscriptions","description":"billing-subscriptions","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"b991760f-c629-4fdd-8190-22c10b8cbd73","gmt_create":"2026-07-23T01:47:01.1182873+08:00","gmt_modified":"2026-07-23T01:47:01.1275753+08:00"},{"catalog_id":"915d9267-a5a3-4ccf-9891-2071a4e7b621","title":"Backend Services (Supabase)","description":"backend-services","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"abe69d15-cb02-4280-a0ab-ea501393eeba","gmt_create":"2026-07-23T01:47:18.3891237+08:00","gmt_modified":"2026-07-23T01:47:18.3953235+08:00"},{"catalog_id":"c870be03-f946-4159-9251-65e9a33f166c","title":"API Reference","description":"api-reference","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"432424cd-bed4-41ac-9229-4e2dd23f746b","gmt_create":"2026-07-23T01:47:54.0624249+08:00","gmt_modified":"2026-07-23T01:47:54.0731978+08:00"},{"catalog_id":"7ed0042c-9ec0-43b4-a5fd-2e4537db9eb9","title":"Mobile Application","description":"mobile-application","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"9caf1b6e-1292-414b-bd72-42b894062757","gmt_create":"2026-07-23T01:47:54.7379497+08:00","gmt_modified":"2026-07-23T01:47:54.7444572+08:00"},{"catalog_id":"071bfed4-c831-4891-9c40-5690a29fc726","title":"Testing Strategy","description":"testing-strategy","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"ce7ef955-edc6-45a1-9418-5d8a50616a1f","gmt_create":"2026-07-23T01:48:09.5091597+08:00","gmt_modified":"2026-07-23T01:48:09.5148755+08:00"},{"catalog_id":"e20612b4-193b-47a4-b22c-9257ae93911a","title":"Deployment \u0026 DevOps","description":"deployment-devops","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"133c1856-915a-46e4-911d-468c6d5f7e6d","gmt_create":"2026-07-23T01:48:40.1474175+08:00","gmt_modified":"2026-07-23T01:48:40.1533975+08:00"},{"catalog_id":"edc4a5d1-b7ae-4062-8673-f2bfd4864bf0","title":"Developer Guidelines","description":"developer-guidelines","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"37cd5a6a-be41-4893-880c-9686df80909b","gmt_create":"2026-07-23T01:49:07.2860255+08:00","gmt_modified":"2026-07-23T01:49:07.3012305+08:00"},{"catalog_id":"023e5a1e-d90e-4f5e-b6a9-6272b9de8086","title":"Job Application Tracker","description":"job-application-tracker","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"e1688bba-ce2d-44bf-8cd9-7b80e2135cb5","gmt_create":"2026-07-23T01:49:12.0590743+08:00","gmt_modified":"2026-07-23T01:49:12.0715356+08:00"},{"catalog_id":"4e6884c3-ec96-4738-b40c-ddece5a2a3a8","title":"Component System","description":"component-system","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"75717c15-f820-47b2-b1bc-d301569048f6","gmt_create":"2026-07-23T01:49:37.7797863+08:00","gmt_modified":"2026-07-23T01:49:37.790785+08:00"},{"catalog_id":"6dc96b36-07c7-4466-bd10-1f0ab817577a","title":"Resume Analysis Engine","description":"resume-analysis-engine","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"0a752f6c-297a-43d7-85b3-d45c13850d0b","gmt_create":"2026-07-23T01:49:59.0908501+08:00","gmt_modified":"2026-07-23T01:49:59.0960746+08:00"},{"catalog_id":"6dcdd10b-114c-4283-8965-a6e63c1641fe","title":"System Architecture","description":"system-architecture","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"e5dc03c8-ce96-427d-8590-dac8fc2a769e","gmt_create":"2026-07-23T01:50:12.3051236+08:00","gmt_modified":"2026-07-23T01:50:12.3155071+08:00"},{"catalog_id":"b55383ee-0af7-4328-bbde-b36f5eb8efdf","title":"Local Storage \u0026 Persistence","description":"local-storage","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"00d944ce-ee63-417b-8e53-dbe2ea6c7362","gmt_create":"2026-07-23T01:50:22.5796691+08:00","gmt_modified":"2026-07-23T01:50:22.584061+08:00"},{"catalog_id":"986ed762-453d-4ce8-bad1-3e06d2ae510a","title":"Trial \u0026 Usage Ledger System","description":"trial-usage-ledger","extend":"{}","progress_status":"completed","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","reference_count":0,"id":"44f8e3aa-0a7f-4ce0-939e-e57818c51674","gmt_create":"2026-07-23T02:11:09.1258283+08:00","gmt_modified":"2026-07-23T02:11:09.1317003+08:00"}],"wiki_overview":{"content":"\u003c/think\u003e\n\nI'll analyze the ApplyGuard PH project structure and generate a comprehensive overview based on the provided information. Let me examine the key files to understand the project architecture.\n\n\u003ctool_call\u003e\n\u003cfunction=read_file\u003e\n\u003cparameter=file_path\u003e\nc:\\ApplyGuard PH\\package.json\n\u003c/parameter\u003e\n\u003c/function\u003e\n\u003c/tool_call\u003e","gmt_create":"2026-07-23T01:20:28.2180889+08:00","gmt_modified":"2026-07-23T01:20:28.2180889+08:00","id":"546c43fa-b6f4-4a73-b331-673cb81af2f0","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3"},"wiki_readme":{"content":"No readme file","gmt_create":"2026-07-23T01:20:10.6560073+08:00","gmt_modified":"2026-07-23T01:20:10.6560073+08:00","id":"c5a9d249-44cd-4840-8aca-de972b81cc84","repo_id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3"},"wiki_repo":{"id":"eb6273e6-6528-4b56-bdbd-222ecb0481b3","name":"ApplyGuard PH","progress_status":"completed","wiki_present_status":"COMPLETED","optimized_catalog":"\".\\n├── .claude\\\\\\n│ └── launch.json\\n├── .github\\\\workflows\\\\\\n│ └── supabase.yml\\n├── docs\\\\\\n│ ├── superpowers\\\\plans\\\\\\n│ │ ├── monetization\\\\\\n│ │ │ ├── 00-architecture.md\\n│ │ │ ├── 01-backend-foundation.md\\n│ │ │ ├── 02-accounts-and-sync.md\\n│ │ │ ├── 03-subscriptions-paymongo.md\\n│ │ │ └── 04-ai-features.md\\n│ │ └── 2026-07-18-hook-frontend-design.md\\n│ └── HANDOFF_QWEN_MAX.md\\n├── mobile\\\\\\n│ └── README.md\\n├── public\\\\\\n│ ├── manifest.webmanifest\\n│ └── sw.js\\n├── scripts\\\\\\n│ └── generate_message_pack.py\\n├── src\\\\\\n│ ├── components\\\\\\n│ │ ├── AccountPage.jsx\\n│ │ ├── AiAssistant.jsx\\n│ │ ├── Layout.jsx\\n│ │ ├── MockInterviewPage.jsx\\n│ │ ├── OffersPage.jsx\\n│ │ ├── ResultView.jsx\\n│ │ ├── ScanForm.jsx\\n│ │ ├── Settings.jsx\\n│ │ ├── Toast.jsx\\n│ │ └── Tracker.jsx\\n│ ├── hooks\\\\\\n│ │ └── useCountUp.js\\n│ ├── lib\\\\\\n│ │ ├── ai.js\\n│ │ ├── analyze.js\\n│ │ ├── billing.js\\n│ │ ├── clipboard.js\\n│ │ ├── cloud.js\\n│ │ ├── csv.js\\n│ │ ├── csv.test.js\\n│ │ ├── entitlement.js\\n│ │ ├── entitlement.test.js\\n│ │ ├── followups.js\\n│ │ ├── followups.test.js\\n│ │ ├── missing.js\\n│ │ ├── missing.test.js\\n│ │ ├── nextaction.js\\n│ │ ├── pricing.js\\n│ │ ├── prompt.js\\n│ │ ├── redflags.js\\n│ │ ├── redflags.test.js\\n│ │ ├── samples.js\\n│ │ ├── samples.test.js\\n│ │ ├── scoring.js\\n│ │ ├── scoring.test.js\\n│ │ ├── share.js\\n│ │ ├── share.test.js\\n│ │ ├── stats.js\\n│ │ ├── stats.test.js\\n│ │ ├── storage.js\\n│ │ ├── supabase.js\\n│ │ ├── sync.js\\n│ │ ├── sync.test.js\\n│ │ └── tone.js\\n│ ├── App.jsx\\n│ ├── auth.jsx\\n│ ├── index.css\\n│ ├── main.jsx\\n│ ├── mobile.js\\n│ └── store.jsx\\n├── supabase\\\\\\n│ ├── functions\\\\\\n│ │ ├── _shared\\\\\\n│ │ │ ├── entitlement.ts\\n│ │ │ ├── http.ts\\n│ │ │ ├── paypal-runtime.ts\\n│ │ │ ├── paypal.test.ts\\n│ │ │ ├── paypal.ts\\n│ │ │ └── prompts.ts\\n│ │ ├── ai-proxy\\\\\\n│ │ │ └── index.ts\\n│ │ ├── cancel-subscription\\\\\\n│ │ │ └── index.ts\\n│ │ ├── capture-paypal-order\\\\\\n│ │ │ ├── .npmrc\\n│ │ │ ├── deno.json\\n│ │ │ └── index.ts\\n│ │ ├── create-checkout\\\\\\n│ │ │ └── index.ts\\n│ │ ├── create-paypal-order\\\\\\n│ │ │ ├── .npmrc\\n│ │ │ ├── deno.json\\n│ │ │ └── index.ts\\n│ │ ├── download-message-pack\\\\\\n│ │ │ └── index.ts\\n│ │ ├── paymongo-webhook\\\\\\n│ │ │ └── index.ts\\n│ │ └── paypal-webhook\\\\\\n│ │ └── index.ts\\n│ ├── migrations\\\\\\n│ │ ├── 001_schema.sql\\n│ │ └── 002_paypal_fulfillment.sql\\n│ └── config.toml\\n├── .gitignore\\n├── README.md\\n├── capacitor.config.ts\\n├── index.html\\n├── netlify.toml\\n├── package-lock.json\\n├── package.json\\n├── vercel.json\\n└── vite.config.js\\n\"","current_document_structure":"WikiEncrypted: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","catalogue_think_content":"WikiEncrypted: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","recovery_checkpoint":"wiki_generation_completed","last_commit_id":"edb6936e072476ebed05ebdd3da543c664abea78","last_commit_update":"2026-07-23T02:11:09.9685072+08:00","gmt_create":"2026-07-23T01:12:19.1131607+08:00","gmt_modified":"2026-07-23T02:11:09.9685072+08:00","extend_info":"{\"language\":\"en\",\"active\":true,\"branch\":\"main\",\"shareStatus\":\"\",\"server_error_code\":\"\",\"cosy_version\":\"1.17.3\"}"}} \ No newline at end of file diff --git "a/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/_module.yaml" "b/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/_module.yaml" new file mode 100644 index 0000000..f92c1fa --- /dev/null +++ "b/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/_module.yaml" @@ -0,0 +1,11 @@ +schema_version: 1 +module_path: frontend_app/account_settings +title: Account & Settings UI +scope: + - src/components/AccountPage.jsx + - src/components/Settings.jsx + - src/components/Toast.jsx +source_files: [] +depends_on: [] +related_to: + - path: frontend_app/app_shell diff --git "a/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/architecture_design.md" "b/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/architecture_design.md" new file mode 100644 index 0000000..4b80c85 --- /dev/null +++ "b/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/architecture_design.md" @@ -0,0 +1,6 @@ +Three sibling React components that compose the top-level user-facing configuration surface: +- `AccountPage.jsx` is a stateful page component that renders four mutually exclusive views based on auth/backend state: loading, backend-not-configured, not-signed-in (email magic-link form), and signed-in (premium tier display, purchased items, sync info, sign-out). It reads identity and entitlement from the shared `useAuth()` context (`../auth.jsx`) and dispatches side effects through `useApp().notify`. +- `Settings.jsx` is a preferences + data-safety panel bound to `useApp().settings`, exposing name, monthly pay floor, and currency inputs plus four data operations backed by `../lib/storage.js` (`backup`, `restoreState`, `resetAll`) and `../lib/csv.js` (`jobsToCSV`). A local `download()` helper creates Blob URLs to trigger browser downloads. +- `Toast.jsx` is a pure presentational overlay rendering the global `toasts` array from `useApp()`, mapping each toast's `tone` to a Tailwind color via a `TONE` lookup table and announcing changes through an `aria-live="polite"` region. + +Dependency direction is one-way: all three components consume only the `useApp()` store and `useAuth()` context; they never import each other. Cross-cutting concerns (file download, CSV export, Message Pack download) are delegated to `../lib/*` modules so the components stay thin view layers. \ No newline at end of file diff --git "a/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/coding_conventions.md" "b/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/coding_conventions.md" new file mode 100644 index 0000000..5b662c4 --- /dev/null +++ "b/.qoder/repowiki/knowledge/en/ApplyGuard PH \342\200\224 Monorepo Root/ApplyGuard PWA Frontend/Account & Settings UI/coding_conventions.md" @@ -0,0 +1,4 @@ +- User feedback is emitted through the shared `useApp().notify(message, tone)` action rather than local alert/dialog, keeping transient messages centralized in the Toast overlay. +- UI sections follow a consistent card pattern: a `
` wrapped in `elev rounded-3xl border border-line bg-card p-6 sm:p-8` with a `

` heading. +- Form inputs share a single `inputCls` string constant and pair each input with a `

{/* Purchased items / Message Pack */} {entitlement?.has_message_pack && ( -
+

Purchased Items

-
+

Message Pack

20 application & follow-up templates

- +
)} {/* Cloud sync */} -
+

Cloud sync

Your tracker has {jobs.length} job{jobs.length !== 1 ? "s" : ""}. Settings and jobs sync @@ -269,14 +259,14 @@ export default function AccountPage() {

{/* Sign out */} -
- +
{/* Privacy & Legal links */} diff --git a/src/components/AiAssistant.jsx b/src/components/AiAssistant.jsx index 3b020af..febc248 100644 --- a/src/components/AiAssistant.jsx +++ b/src/components/AiAssistant.jsx @@ -1,15 +1,55 @@ import { useState } from "react"; +import { m, AnimatePresence } from "motion/react"; import { useAuth } from "../auth.jsx"; import { callAi } from "../lib/ai.js"; import { AI_FEATURES } from "../lib/pricing.js"; +import { useReducedMotion } from "../motion/useMotionConfig.js"; +import { duration, easing } from "../motion/tokens.js"; +import { useCopy } from "../hooks/useCopy.js"; +import Button from "./ui/Button.jsx"; +import { CheckIcon, CopyIcon } from "./ui/icons.jsx"; + +// The generated answer reads like correspondence: it rises in as one sheet, +// then its paragraphs settle one after another rather than appearing at once. +const resultParent = { + hidden: {}, + show: { transition: { staggerChildren: 0.08, delayChildren: 0.06 } }, +}; +const resultLine = { + hidden: { opacity: 0, y: 8 }, + show: { opacity: 1, y: 0, transition: { duration: duration.normal, ease: easing.enter } }, +}; + +// A calm three-bar rhythm for the "AI is drafting" state — a cursor-like pulse, +// not a spinner. Under reduced motion it collapses to a plain label. +function ThinkingRhythm({ reduced }) { + if (reduced) return Thinking…; + return ( + + ); +} export default function AiAssistant({ rawText, intake, settings }) { const { user, tier, usageCount, aiCap, refreshEntitlement } = useAuth(); + const reduced = useReducedMotion(); const [activeTab, setActiveTab] = useState("message"); const [resumeText, setResumeText] = useState(""); const [result, setResult] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); + // The "Copied" flag decays on its own 1.9s timer, and the copy button + // unmounts whenever result is cleared, so no manual reset is needed. + const { copied, copy } = useCopy(); const handleGenerate = async () => { if (!rawText?.trim()) { @@ -37,18 +77,20 @@ export default function AiAssistant({ rawText, intake, settings }) { }; const feature = AI_FEATURES.find((f) => f.id === activeTab); - const tabStyle = (id) => - `px-4 py-2.5 text-sm font-medium rounded-full transition-colors ${ - activeTab === id - ? "bg-brand text-paper" - : "text-ink-soft hover:text-ink hover:bg-panel" - }`; + + const handleCopyResult = async () => { + try { + await copy(result); + } catch { + setError("Couldn't copy automatically. Select the text and copy it."); + } + }; const remaining = Math.max(0, aiCap - usageCount); if (!user) { return ( -
+

AI-powered features

Sign in and upgrade to Premium to unlock: application message generator, @@ -64,18 +106,15 @@ export default function AiAssistant({ rawText, intake, settings }) { if (tier !== "premium") { return ( -

+

AI-powered features

Upgrade to Premium to unlock all four AI features: message generator, deep scam analysis, resume tailoring, and interview prep.

- +

This feature sends the job post to our AI provider for processing. It is processed in memory and never stored. @@ -85,16 +124,16 @@ export default function AiAssistant({ rawText, intake, settings }) { } return ( -

+

AI features

- + {remaining} of {aiCap} uses left this month
- {/* Tabs */} -
+ {/* Tabs — the active pill travels between features (layoutId) */} +
{AI_FEATURES.map((f) => ( ))}
@@ -123,24 +172,19 @@ export default function AiAssistant({ rawText, intake, settings }) { value={resumeText} onChange={(e) => setResumeText(e.target.value)} placeholder="Paste your resume text here…" - className="w-full rounded-xl border border-line bg-paper p-3.5 text-sm text-ink placeholder:text-ink-faint focus:border-brand focus:outline-none resize-y" + className="glass-subtle field-input w-full rounded-xl p-3.5 text-sm text-ink placeholder:text-ink-faint focus:border-brand focus:outline-none resize-y" />
)} {/* Generate button */} - +

This feature sends the post to our AI provider to generate the result. @@ -149,19 +193,67 @@ export default function AiAssistant({ rawText, intake, settings }) { {/* Error */} {error && ( -

+

{error}

)} - {/* Result */} - {result && ( -
-
- {result} -
+ {/* Thinking state — a calm drafting rhythm while the AI works */} + {loading && ( +
+ +

Drafting your {feature?.name}…

)} + + {/* Result — rises in like a sheet of correspondence, then unfolds */} + + {result && !loading && ( + +
+ {feature?.name} + +
+ {reduced ? ( +
+ {result} +
+ ) : ( + + {result.split(/\n{2,}/).map((para, i) => ( + + {para} + + ))} + + )} +
+ )} +
); } diff --git a/src/components/BackgroundCheckPage.jsx b/src/components/BackgroundCheckPage.jsx index 0e3941a..38ba150 100644 --- a/src/components/BackgroundCheckPage.jsx +++ b/src/components/BackgroundCheckPage.jsx @@ -1,34 +1,112 @@ -import { useState } from "react"; -import { Link } from "react-router-dom"; +import { useEffect, useState } from "react"; +import { m } from "motion/react"; import { useAuth } from "../auth.jsx"; +import { useApp } from "../store.jsx"; import { callAi } from "../lib/ai.js"; +import { useReducedMotion } from "../motion/useMotionConfig.js"; +import { duration, easing } from "../motion/tokens.js"; +import { useCountUp } from "../hooks/useCountUp.js"; +import { useCopy } from "../hooks/useCopy.js"; +import Button from "./ui/Button.jsx"; +import { Field, FieldFrame, fieldInputCls } from "./ui/Field.jsx"; +import { BoltIcon, CheckIcon, ChevronRightIcon, CopyIcon } from "./ui/icons.jsx"; import { analyzeUrl, parseUrl, canUseFreeCheck, getFreeChecksUsed, incrementFreeCheck, + formatCheckReport, DAILY_FREE_LIMIT, + VERDICT_LABELS, } from "../lib/backgroundcheck.js"; +// Verdict wording comes from the lib (shared with the copy-report text) so the +// card and the clipboard summary can never disagree. const VERDICT_STYLES = { - credible: { bg: "bg-go-soft", border: "border-go/30", text: "text-go-ink", label: "Looks credible", dot: "bg-go" }, - caution: { bg: "bg-warn-soft", border: "border-warn/30", text: "text-warn-ink", label: "Proceed with caution", dot: "bg-warn" }, - suspicious: { bg: "bg-stop-soft", border: "border-stop/30", text: "text-stop-ink", label: "Suspicious — investigate first", dot: "bg-stop" }, - invalid: { bg: "bg-panel", border: "border-line", text: "text-ink-soft", label: "Invalid URL", dot: "bg-ink-faint" }, + credible: { bg: "bg-go-soft", border: "border-go/30", text: "text-go-ink", label: VERDICT_LABELS.credible, dot: "bg-go" }, + caution: { bg: "bg-warn-soft", border: "border-warn/30", text: "text-warn-ink", label: VERDICT_LABELS.caution, dot: "bg-warn" }, + suspicious: { bg: "bg-stop-soft", border: "border-stop/30", text: "text-stop-ink", label: VERDICT_LABELS.suspicious, dot: "bg-stop" }, + invalid: { bg: "bg-panel", border: "border-line", text: "text-ink-soft", label: VERDICT_LABELS.invalid, dot: "bg-ink-faint" }, }; +// UrlBreakdown — Phase 6 URL analysis. Splits the pasted link into protocol, +// domain, path, and query so the reader sees exactly which part matters. The +// domain is highlighted and underlined; the surrounding protocol/path/query are +// de-emphasised. Segments rule in left-to-right like a marked-up field note. +// It is display-only and re-parses the same string the heuristic scored, so it +// can never disagree with the verdict. Reduced motion renders the final state. +function UrlBreakdown({ input }) { + const reduced = useReducedMotion(); + const parsed = parseUrl(input); + if (!parsed) return null; + + const domain = parsed.hostname.replace(/^www\./, ""); + const subPrefix = parsed.hostname.slice(0, parsed.hostname.length - domain.length); + const path = parsed.pathname && parsed.pathname !== "/" ? parsed.pathname : ""; + const query = parsed.search || ""; + + const segments = [ + { key: "protocol", text: parsed.protocol + "//", role: "dim" }, + subPrefix ? { key: "sub", text: subPrefix, role: "dim" } : null, + { key: "domain", text: domain, role: "domain" }, + path ? { key: "path", text: path, role: "dim" } : null, + query ? { key: "query", text: query, role: "dim" } : null, + ].filter(Boolean); + + return ( +
+

Link breakdown

+
+ {segments.map((seg, i) => ( + + {seg.text} + + ))} +
+

+ The highlighted domain is who you'd + actually be dealing with — the rest of the link can be made to say anything. +

+
+ ); +} + function ScoreGauge({ score, verdict }) { - const style = VERDICT_STYLES[verdict] || VERDICT_STYLES.invalid; const r = 44; const c = 2 * Math.PI * r; - const offset = c * (1 - score / 100); + const target = c * (1 - score / 100); + // Fill from empty on mount, matching the result page's score ring. The + // number counts up alongside; reduced motion shows both instantly. + const [offset, setOffset] = useState(c); + useEffect(() => { + const id = requestAnimationFrame(() => setOffset(target)); + return () => cancelAnimationFrame(id); + }, [target]); + const displayScore = useCountUp(score, 1000); const strokeColor = verdict === "credible" ? "var(--color-go)" : verdict === "caution" ? "var(--color-warn)" : "var(--color-stop)"; return (
- +
- {score} + {displayScore} / 100
@@ -48,7 +126,7 @@ function HeuristicResult({ result }) { const style = VERDICT_STYLES[result.verdict] || VERDICT_STYLES.invalid; return ( -
+
@@ -58,7 +136,7 @@ function HeuristicResult({ result }) {

{result.meta.domain || result.meta.input}

{result.meta.isKnownPlatform && ( -

+

Known platform

@@ -103,7 +181,9 @@ function HeuristicResult({ result }) { } export default function BackgroundCheckPage() { - const { user, tier, usageCount, aiCap, refreshEntitlement } = useAuth(); + const { tier, usageCount, aiCap, refreshEntitlement } = useAuth(); + const { notify } = useApp(); + const { copied: reportCopied, copy: copyReport } = useCopy(); const [url, setUrl] = useState(""); const [companyName, setCompanyName] = useState(""); @@ -117,6 +197,15 @@ export default function BackgroundCheckPage() { const remaining = DAILY_FREE_LIMIT - checksUsed; const aiRemaining = Math.max(0, aiCap - usageCount); + const handleCopyReport = async () => { + if (!heuristicResult) return; + try { + await copyReport(formatCheckReport(heuristicResult)); + } catch { + notify("Couldn't copy the report. Try again.", "error"); + } + }; + const handleQuickCheck = () => { setError(""); setAiResult(null); @@ -160,25 +249,24 @@ export default function BackgroundCheckPage() { return (
{/* Header */} -
-
-