mirror of
https://github.com/computerim/impactflow-discovery.git
synced 2026-08-27 06:20:36 +00:00
Phase 4: task-to-goal integration (Vision side)
Build the boundary the ImpactFlow core time-tracker plugs into. A task maps to a foundation — one of the six stable profile elements (love, strength, mission, vocation, short_term, long_term) — so the tracker can ask "which goal does this build toward?" and post the answer back to Vision. - Models + migration 006: task_mapping (one row per logged time entry). - app/services/foundations.py: the six foundations + a pure, testable work-pattern aggregator (rollup) and a plain-language summary. - app/routers/integration.py (user-scoped; tracker calls as the user or via X-API-Key): GET /foundations, POST/GET /task-mappings, GET /work-patterns?days=N (per-foundation minutes/share/neglected). - Reminder engine now pulls from real work patterns: CheckinCoach takes an optional work-pattern summary (last 14 days) and reflects where time has gone against the person's own words — an observation, never a verdict. - Frontend: dashboard.html (time per foundation + neglected); linked from profile.html. Documented the core-tracker integration contract in the README. Phase 4 completes the Vision module's roadmap on the Discovery side; the core tracker integrates by calling these endpoints. Tests: 86 passing (added pure-aggregator, integration-endpoint, and work-pattern-into-check-in tests; run in-container). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,10 @@ If you need to explain this app in detail, use this mental model:
|
||||
coaching preferences (auto-derived from their profile) and receive periodic
|
||||
check-ins that quote their own words and ask if their direction still holds.
|
||||
A weekly cron calls `POST /discovery/coaching/run` to generate due check-ins.
|
||||
14. (Phase 4) The ImpactFlow core time-tracker maps each logged task to a
|
||||
profile foundation via `POST /discovery/integration/task-mappings`. The
|
||||
rolled-up work patterns drive `/static/dashboard.html` and are fed into the
|
||||
coaching check-ins so they can reflect where time has actually gone.
|
||||
|
||||
Machine-to-machine callers (e.g. the MCP server) skip the OAuth dance and
|
||||
authenticate with `X-API-Key: $IMPACTFLOW_API_KEY` instead. That header
|
||||
@@ -147,21 +151,27 @@ Important files:
|
||||
| `app/static/profile.html` | Browser-based profile display, edit, and confirm actions; links to reflection |
|
||||
| `app/static/reflect.html` | Phase 2 AI-coach reflection chat (mirror loop, applies revisions, affirm) |
|
||||
| `app/static/coaching.html` | Phase 3 coaching preferences form + check-in feed |
|
||||
| `app/static/dashboard.html` | Phase 4 goal dashboard: time per foundation + neglected ones |
|
||||
| `app/static/auth.js` | Shared `authedFetch` helper: sends session cookies, silently refreshes on `401`, redirects to login |
|
||||
| `app/static/style.css` | Shared UI styling |
|
||||
| `app/services/reflector.py` | `ReflectionCoach`: Anthropic-backed mirror loop, JSON parsing, revision filtering |
|
||||
| `app/services/coaching.py` | Deterministic preference generator + `CheckinCoach` (Anthropic check-in text) |
|
||||
| `app/services/foundations.py` | The six foundations + pure work-pattern aggregator (Phase 4) |
|
||||
| `app/routers/coaching.py` | Phase 3 coaching routes: preferences, check-ins, weekly batch `/run` |
|
||||
| `app/routers/integration.py` | Phase 4 task-to-goal integration: foundations, task-mappings, work-patterns |
|
||||
| `alembic/versions/001_initial.py` | Initial database schema migration |
|
||||
| `alembic/versions/002_add_auth.py` | Adds `users`, `refresh_tokens`, and `activity_log` tables |
|
||||
| `alembic/versions/003_add_goals.py` | Adds the goal columns to `discovery_conversation` and `discovery_profile` |
|
||||
| `alembic/versions/004_add_reflection.py` | Adds `reflection_message` and `profile_revision` tables (Phase 2) |
|
||||
| `alembic/versions/005_add_coaching.py` | Adds `coaching_preferences` and `coaching_checkin` tables (Phase 3) |
|
||||
| `alembic/versions/006_add_task_mapping.py` | Adds the `task_mapping` table (Phase 4) |
|
||||
| `tests/conftest.py` | Shared `app_client` fixture (isolated app + temp DB) |
|
||||
| `tests/test_extractor.py` | Unit tests for extraction plumbing, goals, and retry behavior |
|
||||
| `tests/test_reflector.py` | Unit tests for `ReflectionCoach` (mirror, revision filtering, retry) |
|
||||
| `tests/test_coaching_prefs.py` | Unit tests for the deterministic coaching-preference generator |
|
||||
| `tests/test_coaching.py` | Tests for coaching endpoints (preferences, check-ins, due-logic batch) |
|
||||
| `tests/test_coaching.py` | Tests for coaching endpoints (preferences, check-ins, due-logic batch, work-pattern wiring) |
|
||||
| `tests/test_foundations.py` | Unit tests for the pure work-pattern aggregator |
|
||||
| `tests/test_integration.py` | Tests for the task-to-goal integration endpoints |
|
||||
| `tests/test_auth.py` | Tests for the dual-auth dependency (JWT + cookie + API key), token refresh/logout, admin enforcement, and domain allow-list |
|
||||
| `tests/test_profile_edit.py` | Tests for `PATCH /discovery/profile/me` (edit, partial update, lock/`409`) |
|
||||
| `tests/test_reflection.py` | Tests for the reflection endpoints (turns, applied revisions, lock/`409`, history) |
|
||||
@@ -427,6 +437,30 @@ prescribes. The person's answer is recorded in `still_valid`.
|
||||
cadence is due. Eligible = coaching cadence not `off` and an affirmed
|
||||
(locked) profile; due = no prior check-in or the cadence interval has elapsed.
|
||||
|
||||
### 10. Task-to-Goal Integration (Phase 4)
|
||||
|
||||
This is the boundary the ImpactFlow **core time-tracker** plugs into. A task
|
||||
maps to a **foundation** — one of the six stable profile elements: `love`,
|
||||
`strength`, `mission`, `vocation`, `short_term`, `long_term`.
|
||||
|
||||
**Core-tracker contract:** when a user logs time, the tracker (1) fetches the
|
||||
options from `GET /discovery/integration/foundations`, (2) asks the person
|
||||
"which goal does this build toward?", and (3) posts the answer to
|
||||
`POST /discovery/integration/task-mappings` with `{external_task_id,
|
||||
foundation, minutes, task_label?, occurred_at?}`. It calls these endpoints as
|
||||
the user (forwarded session/JWT) or service-to-service with `X-API-Key`.
|
||||
|
||||
- `GET /discovery/integration/foundations` — the six foundations with the
|
||||
person's own text (what the tracker shows). `404` if no profile.
|
||||
- `POST /discovery/integration/task-mappings` — record one logged unit of work.
|
||||
- `GET /discovery/integration/task-mappings?days=N` — the user's mappings.
|
||||
- `GET /discovery/integration/work-patterns?days=N` — per-foundation rollup
|
||||
(minutes, share, task count, last activity) plus `neglected` foundations.
|
||||
Powers the goal dashboard and feeds the coaching reminder engine: a check-in
|
||||
is given a plain-language summary of the last 14 days so it can reflect where
|
||||
time has and hasn't gone — as an observation to check against the person's
|
||||
own words, never a verdict (mirror, not compass).
|
||||
|
||||
## API Reference
|
||||
|
||||
All `/discovery/*`, `/api/me*`, `/api/activity*`, and `/api/admin/*` routes
|
||||
@@ -469,6 +503,10 @@ clients.) `/api/auth/login`, `/api/auth/callback`, `/health`, `/`, and
|
||||
| `POST` | `/discovery/coaching/checkins` | yes | Generate a check-in now |
|
||||
| `PUT` | `/discovery/coaching/checkins/{id}/respond` | yes | Record "is your direction still valid?" |
|
||||
| `POST` | `/discovery/coaching/run` | admin | Weekly batch: generate due check-ins for eligible users |
|
||||
| `GET` | `/discovery/integration/foundations` | yes | The six mappable foundations with the person's own text |
|
||||
| `POST` | `/discovery/integration/task-mappings` | yes | Record a logged unit of work mapped to a foundation |
|
||||
| `GET` | `/discovery/integration/task-mappings` | yes | List the user's task mappings in a window |
|
||||
| `GET` | `/discovery/integration/work-patterns` | yes | Per-foundation work-pattern rollup over a window |
|
||||
|
||||
## Data Model
|
||||
|
||||
@@ -622,6 +660,22 @@ A periodic coaching check-in and the person's response (migration `005`).
|
||||
| `response_note` | text nullable | Optional note with their response |
|
||||
| `acknowledged_at` | datetime nullable | When they responded |
|
||||
|
||||
### `task_mapping`
|
||||
|
||||
One logged unit of work from the core tracker, mapped to a foundation
|
||||
(migration `006`).
|
||||
|
||||
| Column | Type | Notes |
|
||||
| --- | --- | --- |
|
||||
| `id` | string | UUID primary key |
|
||||
| `user_id` | string | FK to `users.id`, indexed |
|
||||
| `external_task_id` | string | Opaque task id from the core tracker (not an FK) |
|
||||
| `task_label` | string nullable | Human label of the task |
|
||||
| `foundation` | string | `love`/`strength`/`mission`/`vocation`/`short_term`/`long_term`, indexed |
|
||||
| `minutes` | integer | Time logged toward it |
|
||||
| `occurred_at` | datetime | When the work happened, indexed |
|
||||
| `created_at` | datetime | UTC |
|
||||
|
||||
## Extraction Details
|
||||
|
||||
`DiscoveryExtractor` is intentionally responsible for plumbing, not business
|
||||
@@ -718,6 +772,14 @@ callback), so the pages hold no tokens of their own.
|
||||
`.../respond`
|
||||
- linked from `profile.html` ("Coaching preferences & check-ins")
|
||||
|
||||
`dashboard.html` (Phase 4 goal dashboard):
|
||||
|
||||
- reads `GET /discovery/integration/work-patterns?days=N` and renders minutes
|
||||
and share per foundation as bars, with a selectable window
|
||||
- surfaces foundations with no logged time and asks whether that matches where
|
||||
the person wants their energy — it observes, it does not prescribe
|
||||
- linked from `profile.html` ("Where your time goes")
|
||||
|
||||
## Configuration
|
||||
|
||||
Populate `.env` with at minimum the Anthropic key and the auth-related
|
||||
|
||||
Reference in New Issue
Block a user