service instructions

This commit is contained in:
John Lancaster
2026-06-28 08:59:17 -05:00
parent d967f58358
commit 517d01abe2
@@ -0,0 +1,53 @@
---
description: Follow these guidelines when editing the services
applyTo: 'src/transcription/services/*.py'
---
# Services
## Structure
- Project core data models defined in [models](../../src/transcription/models.py)
- 1 service class per data model
- Only services directly interact with the database, and only through async methods
- Services are completely independent of one another. Any operation that needs to use more than a single service, which is most of them, needs to have a separate orchestration function.
## Error Handling
- Service-specific errors defined at the top of the respective module and inherit from `AppError`
- Use a context manager for large `try/except` blocks like in [transcription](../../src/transcription/services/transcription.py)
## Checklist
- [ ] Uses `ServiceBase` for common logic
- [ ] CRUD methods created at the top
- [ ] Session kwarg for `AsyncSession` to pass in a session object to each method
- [ ] Services use `self._session_scope` in their methods to pass the session thru.
- Multiple operations on the same object(s) require sharing a session between all the methods used.
## CRUD Methods
- Create, read, update, and delete, created in that order
- Name format `<operation>_<model >`, for example `create_document` or `update_job`
- All services must define these 4 methods first, and in that order
## Transaction Finalization
When a service method accepts an optional `session` kwarg, write methods must follow this rule:
- If `session` is `None`: the method owns the transaction and should `commit()`.
- If `session` is provided: the method must **not** commit; it should `flush()` so IDs and FK values are available to the caller's transaction.
- Use `refresh()` on returned ORM objects when the caller needs DB-populated values (defaults, triggers, merged state).
Prefer implementing this once in `ServiceBase` (for example a `_finalize_write(...)` helper) so CRUD methods stay small and consistent.
Recommended helper behavior:
- Inputs: active session object, original `session` arg (or a boolean ownership flag), and an optional list of objects to refresh.
- Logic: `commit` when service-owned session, `flush` when caller-owned session, then refresh requested objects.
This keeps orchestration functions atomic: they can pass one shared session across multiple services and commit exactly once at the workflow boundary.
# Service Composition
Some operations, like uploading a picutre, require modifications to multiple tables, which can be done by composing methods from the service object into a separate function.