Product app goal sheet
Status: initial draft, open for refinement. Updated: 29 October 2026.
See the PostgreSQL schema for tables, ownership constraints, and remaining persistence decisions.
The schema dependency HLD shows which tables stand alone and which reference other tables.
The Spring Boot container + Supabase PostgreSQL reference design explains the access boundary and request/response HLD.
The product backend guide records what the service implements today: Google sign-in, backend token pairs, and persisted sessions. Profile, API-key, usage, payment, and redeem-code behavior remain planned.
Build a customer-facing astrology API product where users can sign in, try the API, manage access keys, see their usage, and pay for access. Keep the existing documentation app as the internal engineering documentation site, extracting customer-facing pages into a separate product app.
This sheet records requested goals and proposed delivery criteria. Unchecked items are planned work, not implemented capabilities. Suggested responsibilities and policies remain open until agreed.
Requested scope
| Goal | Completion outcome |
|---|---|
| Product app | Home, pricing, developer docs, login, dashboard, and playground form one customer experience. |
| Internal docs | The existing app becomes the internal documentation site; customer pages and content are extracted into the product app. |
| Kotlin backends | A Kotlin/Native service using Ktor and a Kotlin/JVM service using Spring Boot have explicit responsibilities. |
| Google login | Google is the initial sign-in provider. |
| Lightweight profile | Store only the account information needed for identity, API access, usage, and billing. |
| API key creation | Signed-in users can generate keys associated with their account. |
| Request routing | An authenticated request reaches the appropriate API backend. |
| Per-user usage | Requests are attributed to a user and visible in their dashboard. |
| API key revocation | Users can revoke their own keys and stop subsequent access. |
| Rate control | Request limits can be configured and enforced. |
| Razorpay payments | Purchases use a server-created order and a verified payment result. |
| Redeem codes (later) | A user can redeem a code instead of paying, with consumption linked to the user and granted subscription. |
“Lightweight profile” is the working interpretation of “use profile soft not much.” Exact fields remain open.
Pages and user journey
| Page | Initial purpose | Proposed access |
|---|---|---|
| Home | Explain the product and lead visitors to docs, pricing, and the playground. | Public |
| Pricing | Explain plans, included usage, limits, and the purchase flow. | Public; sign in before purchase |
| Developer docs | Explain authentication, endpoints, examples, errors, usage counting, and limits. | Public |
| Login | Start Google sign-in and return the user to their intended page. | Public |
| Dashboard | Show a minimal profile, keys, usage, plan, and payment status. | Signed in |
| Playground | Run example requests and inspect inputs and responses. | Sample access and live access policy to decide |
Proposed primary journey: home or developer docs → Google login → dashboard → create a key → make a request → inspect usage → purchase access when needed.
Existing app and extraction
The current repository has a documentation frontend with optional product pages and a playground. Its HTTP API currently uses an application-level API key; customer accounts, customer-owned keys, usage plans, and billing are additional goals. Production browser requests already need a server-side boundary that owns backend credentials.
- [ ] Inventory existing routes, product copy, developer material, and playground components before moving them.
- [ ] Extract customer-facing pages into the product app and reuse suitable shared components.
- [ ] Keep engineering designs, research, package internals, and operational guides in internal docs.
- [ ] Define public developer docs separately from engineering docs, including ownership of shared API examples.
- [ ] Decide internal-docs hosting, access restrictions, and redirects before switching navigation or domains.
- [ ] Keep both apps buildable during extraction and preserve the existing API while the new boundary is introduced.
Calling the app “internal” does not itself restrict access. Access enforcement is a separate migration requirement to resolve.
Backend responsibilities — proposed
The requested runtimes are fixed goals; this allocation is a starting point for discussion.
| Component | Suggested ownership | Still to decide |
|---|---|---|
| Product frontend | Public pages, Google sign-in entry, dashboard, playground, checkout interface. | Framework, app location, deployment. |
| Kotlin/JVM + Spring Boot | Google sign-in, accounts, backend token pairs, and persisted login sessions. API key records, plans, usage records, Razorpay orders, and payment verification remain planned. | Hosted database provisioning, deployment, and remaining feature contracts. |
| Kotlin/Native + Ktor | API request entry, key validation, rate enforcement, routing to the calculation API, and usage reporting. | Native-compatible engine and libraries, state sharing, deployment. |
| Existing astrology API | Continue serving calculation requests behind the new entry point. | Long-term retention versus migration to Kotlin. |
The Native/Ktor service needs a feasibility check before this split is accepted. No calculation rewrite is assumed in the first release. Define how revocations, rate policies, and account entitlements reach the request-serving service before implementation.
Implemented today in the Spring Boot service: Google sign-in, backend access/refresh token issuance, and database-backed session validation. The service does not yet expose profile, key, usage, payment, or redeem-code routes.
Capability checklist and acceptance criteria
Identity and profile
- [ ] Google sign-in creates or retrieves an account using a stable provider identity.
- [ ] A user can sign out; failed or cancelled login offers a clear retry path.
- [ ] Track user-owned sessions, support finite and non-expiring sessions, and allow individual or all-session revocation as described in the schema.
- [ ] Keep
app_userto ID and timestamps; store provider subject and contact inlogin_identity, and optional display name in a user-ownedprofileas described in the schema. - [ ] Account data, keys, usage, and payment history are visible only to their owner.
API keys
- [ ] A signed-in user can create a named key; show its full value once and retain a non-reversible verifier.
- [ ] List key labels, identifying prefixes, creation dates, and current status without exposing full secrets.
- [ ] A user can revoke their own key; define and verify the maximum revocation propagation delay.
- [ ] Invalid and revoked keys cannot reach the calculation backend.
- [ ] Customer keys and internal backend credentials remain separate; internal credentials stay out of browser assets and logs.
Key count limits, expiry, rotation, and scopes remain open. They are not assumed for the initial release.
Routing, counting, and request limits
- [ ] Resolve an accepted key to its owning user before forwarding a request.
- [ ] Forward only supported routes and methods; preserve relevant responses and correlation information.
- [ ] Attribute requests across all of a user’s keys to that user, with optional per-key breakdown.
- [ ] Show usage for a clearly identified reporting period in the dashboard.
- [ ] Define whether rejected, failed, retried, and timed-out requests count toward displayed usage and paid allowance.
- [ ] Make usage reporting resilient to duplicate delivery and document any reporting delay.
- [ ] Enforce configurable request rates across service instances; define burst and sustained limits.
- [ ] Distinguish a short-term rate limit from an exhausted plan allowance, with documented recovery behavior.
- [ ] Define behavior when key validation, rate state, or usage storage is unavailable.
The product playground should use the same entitlement and counting policies as customer API calls unless an explicit exception is agreed.
Razorpay payments through orders
Requested approach: the backend creates a Razorpay order for a selected offering; the frontend opens checkout using that order; the backend verifies the payment result before granting access. Exact integration contracts will be verified against provider documentation during implementation.
- [ ] Determine price, currency, and purchased entitlement on the server.
- [ ] Associate the provider order with the signed-in user and a local purchase record.
- [ ] Verify payment authenticity and the required successful payment state before granting entitlement.
- [ ] Handle browser callbacks and provider notifications without granting the same entitlement twice.
- [ ] Show pending, successful, failed, and cancelled outcomes; reconcile payments when the browser never returns.
- [ ] Define how refunds, disputes, and expired or unused purchases affect access.
Order-based purchases are the initial direction. Recurring subscriptions, credit packs, allowance periods, and upgrade rules remain decisions rather than implied features.
Redeem codes — later phase
- [ ] Define codes that grant a subscription without payment, with active state and optional redemption expiry.
- [ ] Track the consuming user and granted subscription as described in SCHEMA.md.
- [ ] Create the grant and consumption record atomically; retries must not grant duplicate access.
- [ ] Agree code limits, eligibility, and subscription stacking before enabling redemption.
Delivery milestones
| Milestone | Deliverable | Exit criteria |
|---|---|---|
| 1. Agree foundations | App ownership, backend split, runtime feasibility, and initial commercial model. | Record decisions for the blocking questions below. |
| 2. Separate the apps | Product page structure and retained internal docs. | Both apps build; content ownership and internal access policy are clear. |
| 3. Establish identity | Google login, sessions, minimal profile, protected dashboard. | Sign-in, sign-out, and account isolation are verified. |
| 4. Enable API access | Key creation/revocation and authenticated backend routing. | Accepted keys work; invalid, revoked, and foreign-owned key operations are rejected. |
| 5. Meter and control usage | User counts, dashboard usage, rate limits, allowance policy. | Counting semantics, concurrency, duplicate reporting, and enforcement are verified. |
| 6. Enable purchases | Razorpay order flow and entitlement updates. | Payment success, failure, pending state, duplicate notifications, and reconciliation are verified in a test environment. |
| 7. Prepare release | Developer docs, migration, operational visibility, and end-to-end checks. | A user can sign in, purchase access, create a key, call the API, view usage, and revoke access. |
Decisions to refine next
| Priority | Question | Current position |
|---|---|---|
| Blocking | What work belongs in Native/Ktor versus Spring Boot? | Allocation above is proposed. |
| Blocking | Must the Native service run as a native binary, and on which host? | Kotlin/Native requested; hosting and engine feasibility open. |
| Blocking | Do we retain the current calculation API or port it? | Retain initially is proposed; no port authorized by this sheet. |
| Blocking | What does a purchase buy? | Order-based payment requested; plans, credits, periods, and renewal behavior open. |
| Before API access | What counts as one request and what consumes allowance? | Open, including retries, failures, and multi-call playground actions. |
| Before enforcement | What are the rate and quota limits and revocation delay? | Open; no numeric defaults chosen. |
| Before app extraction | Where do product, public developer docs, and internal docs live? | Separate customer product app requested; domains and internal access open. |
| Before identity | Which profile fields and session strategy are needed? | Google only initially; minimal profile proposed. |
| Before live playground | Is sample mode public, and do live requests require a plan? | Open. |
| Before persistence | Which database and shared enforcement store will be used? | Supabase PostgreSQL selected; direct Spring JDBC access. Request tracking will be asynchronous; implementation remains open. |
Refinement record
Update this sheet as decisions are made. Mark a goal complete only when its acceptance criteria have evidence; record scope changes here so later implementation follows the agreed plan.
| Date | Decision or scope change | Status |
|---|---|---|
| 2026-10-28 | Capture the initial product pages, docs extraction, Kotlin runtimes, Google login, minimal profile, API access controls, usage, and Razorpay order payments. | Requested goals; implementation pending |
| 2026-10-28 | Select D1 and draft minimal users, provider identities, subscriptions, and subscription-scoped request usage. | Superseded by the Supabase PostgreSQL selection below; transaction ID meaning and plan codes still need confirmation |
| 2026-10-29 | Rename the subscription request ledger from subscription_usage to subscription_tracking. |
Draft migration, schema guide, and Kotlin mapping updated |
| 2026-10-29 | Select Supabase PostgreSQL with direct Spring JDBC access; apply the schema manually and keep Flyway test-only. | Local schema and JDBC configuration implemented; hosted provisioning pending |
| 2026-10-29 | Implement Google sign-in, backend access/refresh token pairs, and persisted login sessions. | Implemented; JVM tests pass locally; live Google login requires a matching client ID. Refresh exchange, sign-out, profile, keys, usage, payments, and redemption pending |
Current references
- Product backend guide: current service capabilities, configuration, routes, and documentation map.
- Authentication: Google verification, token claims, sessions, and failure paths.
- HTTP API: implemented routes, examples, and error contract.
- Database schema: tables, relationships, ownership rules, and manual application.
- Production architecture: proposed Cloudflare container and Supabase PostgreSQL path.
- Local development: Compose, host JVM, configuration, IDE, and commands.
- Native builds: GraalVM native compilation and reflection registration.
- Repository overview: current docs app, product flags, playground behavior, and production credential boundary.
- HTTP API guide: existing calculation API behavior and entry points.
- Current frontend pages: source pages to inspect during extraction.
- Current API app: existing backend host to retain or migrate deliberately.