mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-17 01:49:35 -05:00
7534e8abe7
Describe how GET /api/openapi.json sets info.version via get_version_from_setup() (setup.py at runtime, with TIMETRACKER_VERSION or APP_VERSION overrides and Flask APP_VERSION fallback), and point contributors to the same rules in version management and project structure docs. Update the documentation audit entry for the former hardcoded OpenAPI version gap, document tests/test_api_route_contract.py and the refined test_api_v1 isolation guidance in the testing strategy, add a quick-reference pytest invocation for the contract suite, and note info.version in the API consistency audit next to the OpenAPI references.
3.4 KiB
3.4 KiB
API Consistency Audit
This document records the API consistency audit performed for the TimeTracker backend, REST API, and native clients (desktop and mobile). It describes findings and the standardized contracts adopted.
1. Response shapes
1.1 Success responses
- Helpers in
app/utils/api_responses.pydefinesuccess_response()(returns{ "success": true, "data"?, "message"?, "meta"? }) andpaginated_response()(items indata, pagination inmeta.pagination). - Actual API uses a different convention: list endpoints return resource-named key + top-level pagination, e.g.
{ "time_entries": [...], "pagination": {...} },{ "projects": [...], "pagination": {...} }. Single-resource responses use a singular key:{ "time_entry": {...} },{ "project": {...} },{ "timer": {...} }. - Contract (kept for compatibility): List =
{ "<resource_plural>": [...], "pagination": { page, per_page, total, pages, has_next, has_prev, next_page, prev_page } }. Single ={ "<resource_singular>": {...} }. Created (201) ={ "message"?, "<resource_singular>": {...} }or similar. Clients depend on these keys; we do not switch todata/meta.
1.2 Error responses (standardized)
- Contract: All API v1 error responses (4xx/5xx) include:
error(string): user-facing message (backward compatible).message(string): same or more detail.error_code(string, optional): machine-readable code, e.g.unauthorized,forbidden,not_found,validation_error,no_active_timer.errors(object, optional): field-level validation errors, e.g.{ "field_name": ["message1", "message2"] }.- For 403 scope errors:
required_scope,available_scopesmay also be present.
1.3 Validation errors
- Contract: Any 400 due to invalid input uses the same structure:
error_code: "validation_error"and, when applicable, anerrorsobject with field-level messages. Marshmallow validation useshandle_validation_error(); manual validation usesvalidation_error_response().
2. Pagination
- Contract: List endpoints support query params
page(default 1) andper_page(default 50, max 100). Response includes"pagination": { "page", "per_page", "total", "pages", "has_next", "has_prev", "next_page", "prev_page" }. The list key is resource-specific (e.g.time_entries,projects), notitems.
3. Auth / token handling
- Token extraction (Bearer, Token, X-API-Key) and
@require_api_token(scope)are consistent. Auth error responses includeerror_code(unauthorized,forbidden) for consistent machine-readable handling.
4. Date/time
- Contract: Dates and datetimes use ISO 8601. Request parsing accepts
YYYY-MM-DDandYYYY-MM-DDTHH:MM:SS/YYYY-MM-DDTHH:MM:SSZ. Serialization format (e.g. UTC or server local) is documented in the REST API reference.
5. Sort / filter
- Filter query parameters are resource-specific and documented per endpoint. Optional
sort/orderconventions may be documented for list endpoints that support them.
6. References
- REST API reference: REST_API.md — endpoints, request/response formats, pagination, errors.
- OpenAPI:
/api/openapi.jsonand Swagger UI at/api/docs— aligned with this contract where updated.info.versionfollowsget_version_from_setup()(fromsetup.py, with optionalTIMETRACKER_VERSION/APP_VERSIONoverrides); seeapp/routes/api_docs.py.