Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:57:06 +08:00
commit b2b8396294
6 changed files with 183 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "airbot-backend",
"description": "Backend architecture, Kotlin coroutines, and SQL/DAO rubrics for AIRBot reviews.",
"version": "0.1.0",
"author": {
"name": "AIRBot Team",
"email": "zhongweili@tubi.tv"
},
"skills": [
"./skills"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# airbot-backend
Backend architecture, Kotlin coroutines, and SQL/DAO rubrics for AIRBot reviews.

53
plugin.lock.json Normal file
View File

@@ -0,0 +1,53 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:sids/airbot:plugins/airbot-backend",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "dbf8aefd46148e32500f17eba1e1c16f6ddf3aef",
"treeHash": "289f90609f8687fc60cdb7f6f291c97652ac9950dcd4022ad62764dc4c97b859",
"generatedAt": "2025-11-28T10:28:20.951553Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "airbot-backend",
"description": "Backend architecture, Kotlin coroutines, and SQL/DAO rubrics for AIRBot reviews.",
"version": "0.1.0"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "74a3da174db320acd972bc28373e913ec897d2e377357479ba6929971acecb86"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "96237082257e8e260f6201649acb283c7cc41c282cce521b5351695b833597dd"
},
{
"path": "skills/kotlin-coroutines/SKILL.md",
"sha256": "bdd1e5e7fbf4c8649790dea7a912b7568d20ee00de6c4cd596bddeb4cc7507c7"
},
{
"path": "skills/backend-code-organisation/SKILL.md",
"sha256": "8215c297cefdedef7d199d0060f4ab659e39e5ec0f7aebabdea299ca26cc7399"
},
{
"path": "skills/sql-dao/SKILL.md",
"sha256": "e609ad1a3c70cc499643fa3ddbf3181365ddd3d0e9696953af45025a22f523be"
}
],
"dirSha256": "289f90609f8687fc60cdb7f6f291c97652ac9950dcd4022ad62764dc4c97b859"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,45 @@
---
name: backend-code-organisation
description: Kotlin backend layering and packaging guidelines
license: MIT
---
## Mission
- Keep backend services modular: resources handle transport, managers own business logic, and data access stays isolated.
- Maintain clean dependency flow across modules (`service``core``models`) to encourage reuse and testability.
## Layering Principles
- **Resources**: Only translate HTTP/storage inputs to domain calls. No database or cross-service logic. Convert `SecurityContext` early.
- **Managers**: Encapsulate business rules; coordinate helpers, other managers, workflows, and DAL components. Break cycles by separating read/write responsibilities or introducing controllers.
- **Helpers/Services**: Reusable integrations (feature flags, external clients). Centralize external service calls to simplify retries and upgrades.
- **Repos/DAL/DAO**: Keep database interactions single-purpose. Compose multi-step transactions in repos/DAL; keep DAO calls single query.
- **Utils/Validators/Transformers**: Pure functions and extensions only; avoid hidden state.
- **Cache Managers**: Inject Redis/Lettuce clients, expose typed `get`/`invalidate` helpers.
## Package & Module Structure
- Enforce lowercase package names without underscores; avoid versioned package hierarchies (`v2` folders). Prefer `managers.slots` over `managers.slots.v2`.
- Organize by responsibility: `managers`, `helpers`, `utils`, `dao`, `workflows`, etc. Mirror structure in tests.
- Module boundaries:
- `core`: managers, helpers, data access, transient models. May depend on `models`.
- `service`: Dropwizard resources, configuration, application wiring; no direct DB access.
- `console-service`: Console-specific resources/auth; depends on `core`.
- `client`: Outbound clients; depend only on `models`.
- `models`: Shared API/data contracts; no dependencies.
## Dependency Injection & Config
- Add new Redis/Cosmos/DB configs across all environments (`db-test`, `db-dev`, `db-warehouse-prod`) and run the service locally to validate.
- Annotate injectable classes with `@Singleton` when appropriate.
- Only use `@Named` when multiple bindings of the same type exist; otherwise default bindings suffice.
- Centralize client construction in DI modules to enforce consistent timeouts and hosts.
## Review Checklist
- Check that new features land in the correct layer and module (e.g., resources calling managers, not DAOs).
- Ensure helpers/managers do not introduce cyclic dependencies; suggest splitting read/write flows or using controller orchestrators.
- Verify repos/DAL enforce validation and error translation before returning data.
- Confirm new package or module names remain lowercase and idiomatic; flag attempts to create `v2` package forks.
- Audit DI modules for duplicate provider methods and proper scoping.
## Tooling Tips
- `Glob` for `*.kt` within `service/` or `core/` to inspect layer usage.
- `Read` DI modules when new bindings appear to ensure wiring matches guidelines.
- `Grep` for `@Named` or direct DAO usage inside resources to catch misplaced logic.

View File

@@ -0,0 +1,28 @@
---
name: kotlin-coroutines
description: Coroutine usage guardrails for Kotlin backend reviewers
license: MIT
---
## Mission
- Preserve non-blocking performance characteristics by enforcing clear coroutine boundaries.
- Prevent thread pool exhaustion, deadlocks, and latency spikes caused by mixing blocking and suspend flows.
## Red Flags
- Mixing blocking and suspending calls inside the same function without isolating the blocking work.
- Calling `runBlocking` anywhere other than top-level entrypoints (resources, `main`) or when explicitly bridging to blocking code with the correct dispatcher.
- Using `async { ... }.await()` immediately, or using `async` just to change dispatchers.
- Wiring `AsyncResponse` (Dropwizard) to wrap blocking DAO calls instead of true suspend flows.
## Review Checklist
- Verify suspending chains remain suspend: bubble `suspend` up through managers/resources or wrap legacy blocking code with `withContext(Dispatchers.IO)`.
- Ensure blocking functions stay blocking all the way up the call stack; prefer dedicated blocking helpers (e.g., `getUserBlocking`) rather than ad-hoc `runBlocking`.
- When bridging to suspend from non-suspend contexts, check the dispatcher passed to `runBlocking` matches the underlying workload (usually `Dispatchers.IO`).
- Confirm `AsyncResponse` is only applied to non-blocking suspend flows (Cosmos, service clients with `await`/`executeAwait`). Flag usages that simply wrap JDBI or other blocking calls.
- Look for nested coroutine builders. Replace `async/await` pairs used sequentially with direct calls; use concurrent `async` only when awaiting later.
- Ensure dispatcher changes use `withContext`, not `async`, and that blocking calls inside suspend functions are guarded with the appropriate context.
## Tooling Tips
- `Grep` for `runBlocking`, `.await()`, `executeSync`, or `AsyncResponse` to inspect how coroutines and blocking APIs mix.
- `Read` affected managers/resources to trace whether suspend functions bubble correctly.
- `Glob` modules like `*Manager.kt`, `*Resource.kt`, and `*Dao.kt` when you need broader context about call chains.

42
skills/sql-dao/SKILL.md Normal file
View File

@@ -0,0 +1,42 @@
---
name: sql-dao
description: SQL data access best practices for AIRBot reviewers
license: MIT
---
## Mission
- Guard database performance and correctness by enforcing disciplined DAO/DAL patterns.
- Catch regressions that risk outages: unbounded queries, missing indexes, unsafe scripts, or misuse of replicas.
## Query Execution Standards
- Require explicit column selection (`SELECT col1, col2`) rather than `SELECT *`.
- Prefer synchronous flows within `jdbi.inTransaction {}`; avoid mixing suspend calls inside transactions.
- Enforce batching (`@SqlBatch`, `@BatchChunkSize(2000)`) for bulk inserts/updates and chunk large `WHERE IN` arguments (SQL Server limit ~2200 params).
- Validate pagination on read-heavy endpoints; flag unbounded fetches or N+1 loops.
- Ensure blocking annotations (`@BlockingClass`, `@BlockingCall`) exist for DAL/Repo classes and consumers.
- Confirm master vs. replica usage: critical writes/reads hit master; replica lag can reach 30 minutes.
## Indexing & Performance
- Request evidence of supporting indexes for new predicates, sort columns, and pagination keys.
- Encourage use of table aliases/prefixes in JOINs to maintain clarity.
- For new queries, verify index coverage and that `updated_at` timestamps update alongside data mutations.
- Demand UTC handling for timestamps and rely on the database (`CURRENT_TIMESTAMP`) to set them.
## Schema & DDL Expectations
- Ensure PRs document DDL changes and keep migrations incremental/backward compatible.
- Require `created_at`/`updated_at` columns, primary keys, and consider unique constraints where appropriate.
- Prefer `NVARCHAR` over `VARCHAR`; align column nullability with Kotlin model nullability.
- Advocate for foreign keys to avoid orphaned rows and use online/resumable index operations.
## Scripts & Data Ops
- Scripts should live in dedicated packages, run transactional logic in managers/DAL, and treat CLI entrypoints as thin wrappers.
- Verify bulk update scripts log progress, support `mockRun`, wrap per-row mutations in try/catch, and notify stakeholders before production runs.
## Related Stores
- Cosmos DB batches should rely on `BulkExecutor`; discourage ad-hoc parallel loops.
- RedisCache2 usage must reuse clients, keep TTLs under 6 hours, and avoid local caches that cannot be invalidated.
## Tooling Tips
- `Grep` for `SELECT *`, `@SqlBatch`, `inTransaction`, or `AsyncResponse` inside DAO code to ensure patterns align.
- `Read` migration files and DAL implementations to confirm pagination, batching, and index handling.
- `Glob` `*Dao.kt`, `*Repository.kt`, `*Script.kt` to review related data access or scripting changes together.