Files
Rocky 0af35d44f4 Establish secure account and managed AI backend
Provide the production foundation for Apple identity, immutable credits, referrals, integrity checks, managed providers, and hardened Docker deployment.
2026-08-16 14:46:23 +08:00

73 lines
4.7 KiB
Plaintext

OSGAccountServer is a private backend for OSGKeyboard.
- Use Kotlin 2.1+ with Ktor 3 and JDK 21.
- Organize code by business feature.
- Route handlers only validate and map HTTP.
- Services own business rules; repositories own persistence.
- Use constructor injection and explicit interfaces at external boundaries.
- Never log credentials, Apple subjects, audio, prompts, transcripts, or model output.
- Store monetary-like credit values as integers and use immutable ledger entries.
- Require idempotency for credit grants, reservations, settlement, refunds, and StoreKit events.
- Keep BYOK and local OSGKeyboard features independent from this service.
- Apply SOLID, DRY, KISS, YAGNI, and OWASP guidance.
- Add tests for success, failure, replay, concurrency, and boundary conditions.
- Do not commit secrets or production identifiers beyond public bundle/domain names.
# OSGAccountServer engineering rules
- Use Kotlin 2.1.20+, Ktor 3, JDK 21 and Gradle Kotlin DSL.
- Organize code by business feature under `features/`.
- Keep route handlers limited to request/response mapping.
- Put business rules in services and persistence in repositories.
- Use constructor injection and small, testable interfaces.
- Follow SOLID, DRY, KISS, YAGNI and OWASP guidance.
- Never log credentials, Apple identifiers, audio, prompts, transcripts or model output.
- Never store provider API keys in source control or container images.
- Use integer credits. Never use floating point for balances or billing.
- Credit mutations must be transactional, append-only and idempotent.
- Provider failures must release reserved credits; balances must never become negative.
- Sign in with Apple tokens must be verified server-side, including signature, issuer,
audience, expiry and nonce.
- Existing referral rewards require a qualified usage event; registration alone is not
sufficient for the main reward.
- Public APIs require validation, rate limiting and stable error codes.
- Database migrations are immutable after release.
- Tests must cover success, failure, replay, concurrency and boundary conditions.
- Do not expose MySQL or internal admin routes to the public network.
# OSGAccountServer
- Use Kotlin 2.1+ with JDK 21, Ktor, kotlinx.serialization, Exposed, HikariCP, Koin, and Kotest.
- Organize code by business feature under `features/`; keep routes thin, business logic in services, and persistence behind repositories.
- Apply SOLID, DRY, KISS, YAGNI, and OWASP practices.
- Store money-like credits as integer units and update balances only through immutable, idempotent ledger transactions.
- Never log tokens, Apple subjects, provider credentials, audio, prompts, transcripts, or generated responses.
- Keep all external providers behind interfaces and use deterministic fakes in tests.
- Require tests for success, validation, replay, concurrency, timeout, and failure/refund paths.
- Do not add a dependency unless the standard library or existing stack cannot solve the problem clearly.
# OSGAccountServer
- Use Kotlin 2.1+ with Ktor 3, JDK 21, and Gradle Kotlin DSL.
- Organize code by business feature: auth, account, credits, referrals, integrity, gateway.
- Keep routes limited to transport concerns; put business rules in services and persistence in repositories.
- Use constructor injection and interfaces at every external boundary.
- Follow SOLID, DRY, KISS, YAGNI, and OWASP guidance.
- Store no audio, prompts, transcripts, or generated response bodies.
- Never log secrets, Apple subjects, credentials, tokens, or user content.
- Keep all credit amounts as integers. Ledger rows are immutable and all writes are idempotent.
- Use database transactions and row locks for balance, reservation, settlement, and referral rewards.
- Require tests for success, failure, replay, concurrency, boundary, and provider-timeout paths.
- Keep public APIs versioned and document them in OpenAPI before mobile integration.
- Do not commit environment files, private keys, provider credentials, or production identifiers.
# OSGAccountServer
- Use Kotlin 2.1.20 or newer, Ktor 3, JDK 21, and Gradle Kotlin DSL.
- Organize code by business feature under `features/`.
- Route handlers only validate transport input and produce responses.
- Services own business rules; repositories own database access.
- Use constructor injection and explicit interfaces at external boundaries.
- Store money-like credits as integers and preserve an immutable ledger.
- Make every externally retried mutation idempotent.
- Never log tokens, Apple subjects, audio, prompts, transcripts, or model responses.
- Keep provider credentials and signing keys in environment-backed secret storage.
- Follow SOLID, DRY, KISS, YAGNI, and OWASP guidance.
- Add tests for success, validation, replay, concurrency, timeout, and rollback paths.