# AGENTS.md ## Purpose This document is a working guide for coding agents in this repository. It captures the current architecture, conventions, and safe execution workflow for making reliable changes. ## Pair Working Mode - Work as a pair with the repository owner, not as an isolated implementer. - Before substantial changes, restate the task briefly and inspect the existing code or docs first. - Surface assumptions, tradeoffs, and blockers early instead of silently picking risky directions. - Prefer small, reviewable increments when the product direction is still being shaped. - When requirements are exploratory, help turn them into concrete workflows, domain language, and next implementation steps. - Do not rewrite broad areas of the codebase without clear justification from the current task. - Preserve user changes in the worktree and treat uncommitted files as active collaboration unless told otherwise. ## Repository Layout - `backend/`: ASP.NET Core (`net9.0`) API using FastEndpoints, EF Core (PostgreSQL), Stripe, Azure Blob Storage, and ASP.NET Identity. - `frontend/`: Vue 3 + Vite + Vuetify + Pinia + Vue Router + Tailwind CSS SPA. - `.github/workflows/`: deploy pipelines for backend (Azure Web App) and frontend (Azure Static Web Apps). ## Local Runbook ### Backend - Prereqs: .NET 9 SDK, Docker, PostgreSQL container. - Start database: - `cd backend` - `./scripts/start-infrastructure.sh` - Run API: - `dotnet run` (from `backend/`) - Swagger/OpenAPI UI in dev: - `/api` ### Frontend - Prereqs: Node/npm, local HTTPS cert files expected by Vite: - `frontend/localhost-key.pem` - `frontend/localhost.pem` - Commands: - `cd frontend && npm install` - `npm run dev` - `npm run build` ## Backend Architecture ### Composition Root - Entry point: `backend/Program.cs`. - Registers: - Web services/auth (`backend/DependencyInjection.cs`) - Infrastructure services (`backend/Infrastructure/DependencyInjection.cs`) - Modules: Identity, Creators, Contents, Memberships, Tipping, Messaging. - Each module has: - `Add{Module}Module(...)` to register DbContext/services. - `Use{Module}ModuleAsync()` to auto-run migrations at startup. ### API Style - FastEndpoints-based handlers. - Pattern: request/response records + optional FluentValidation validator + handler class. - Tagging via `Options(o => o.WithTags("..."))`. - File upload handlers call `AllowFileUploads()`. ### Data Boundaries - Separate DbContext per module: - Identity, Creators, Contents, Memberships, Tipping, Messaging. - Migrations are module-scoped under each `Modules/*/Migrations` folder. ### Auth/Security - JWT is generated manually in `Infrastructure/Security/GenerateJwtToken.cs`. - Refresh-token flow is implemented in Identity handlers (`/api/users/login`, `/api/users/refresh`). - User claim helpers live in `Infrastructure/Security/ClaimsPrincipalExtensions.cs`. ### Payments/Stripe - Tip checkout: `Infrastructure/Payments/Stripe/Services/StripeTipProcessor.cs`. - Membership checkout: `Infrastructure/Payments/Stripe/Services/MembershipPaymentProcessor.cs`. - Webhook endpoint: `Modules/Memberships/Handlers/StripeWebhookEndpoint.cs`. - Creator onboarding/status/revoke Stripe: - `/api/stripe/connect` - `/api/stripe/check-status` - `DELETE /api/stripe` ### Blob Storage - `IBlobStorage` implemented by `AzureBlobStorage`. - Upload size/type checks are enforced there (10 MB max + content-type validation). ## Frontend Architecture ### Bootstrap - `frontend/src/main.js` wires Vue app + Pinia + Vuetify + Router + i18n + Google OAuth + Toasts. ### Routing - Defined in `frontend/src/router/router.js`. - Route guards enforce: - `meta.requiresAuth` - `meta.notAuthenticated` - Creator public route convention: `/@:creator`. ### State Management - Pinia stores: - `authStore`: token lifecycle + refresh concurrency guard. - `userProfileStore`: current user profile and account edits. - `creatorProfileStore`: creator-owned profile actions. - `brandingStore`: creator page branding fetched from slug route param. ### API Client - Axios client in `frontend/src/plugins/api.js`. - Injects bearer token, proactively refreshes near expiry, retries once on 401. ## High-Value Domains - Identity and social login (`Modules/Identity/*`, `frontend/src/views/auth/*`). - Creator public profile and management (`Modules/Creators/*`, `frontend/src/views/creators/*`, `frontend/src/views/profile/*`). - Monetization: - Tips (`Modules/Tipping/*`, creator donation UI) - Memberships (`Modules/Memberships/*`, Stripe webhook orchestration) - Content albums/photo upload (`Modules/Contents/*`). - Messaging thread/replies (`Modules/Messaging/*`). ## Agent Working Rules For This Repo 1. Keep module boundaries intact. Do not couple DbContexts across modules. 2. When adding endpoints, follow existing FastEndpoints pattern with validator + explicit route + tag. 3. If schema changes are needed, generate migration in the matching module only. 4. Preserve token refresh behavior in frontend client/store; avoid introducing parallel refresh races. 5. For file uploads, enforce content-type/size limits and reuse blob path conventions. 6. Keep creator route contract stable (`/@slug`) because frontend and backend both depend on it. 7. Do not commit secrets. Existing appsettings include sensitive-looking values; treat as legacy and avoid propagating. ## Validation Checklist Before Finishing - Backend: - `cd backend && dotnet build` - run affected endpoint flows if change touches handlers/auth/payments/storage - Frontend: - `cd frontend && npm run build` - validate affected route/store interactions in browser - If migrations were changed: - ensure module context name/output directory remain consistent with `backend/scripts/add-migration.sh`. ## Notes / Known Sharp Edges - Frontend expects `VITE_API_URL` in API plugin; `src/config.js` uses `VITE_APP_API_URL` naming. Keep env usage consistent when editing. - `GetReceivedTips` currently resolves tipper with `tip.CreatorId` instead of `tip.CreatedBy`; verify intent before refactoring. - Some style/formatting is inconsistent across JS/Vue/C# files; minimize churn to touched lines.