TACTIQ is a futsal decision-training app. Coaches author structured scenarios; only a fully reviewed structured scenario can become publicly playable.
Each structured contentJson payload uses these exact values:
- Defense type:
front_press,central_block,wide_funnel,one_v_one,numerical_advantage, ornumerical_disadvantage. - Player action:
pass,dribble, ormove. - Explanation kind:
observe,benefit,risk, andremember— exactly one of each is required.
The payload also contains the pitch, actor, allowed actions, preferred and alternative answers, timeline, highlights, and review flags. A timeline must have valid ordered time ranges, and every explanation highlight must point to an existing player, zone, or supported path.
Review each scenario in this order:
- Confirm the source and set
review.sourceReviewedtotrue. - Play the full timeline, then verify each explanation’s time range and that
its visual highlight is aligned with the animation; set
review.timelineReviewedandreview.explanationsReviewedtotrue. - Call
POST /api/content/scenarios/:id/reviewwith{ "status": "reviewed", "sourceTitle": "…", "sourceUrl": "…" }and thex-review-keyheader matchingCONTENT_REVIEW_KEY.
The server must configure CONTENT_REVIEWER_NAME together with
CONTENT_REVIEW_KEY. The endpoint records that server-owned reviewer name,
the normalized source title and URL, and the server timestamp in one database
update. It never accepts reviewer identity from the request body. Moving a
scenario back to draft or pending clears those audit fields so an earlier
approval cannot be mistaken for the current content. The same update stores the
exact reviewed content snapshot; any later content edit invalidates publication
and attempt submission until the scenario is reviewed again.
Publication requires all three flags (sourceReviewed, timelineReviewed, and
explanationsReviewed) plus valid structured content containing all four
explanation kinds. The endpoint returns a Korean 409 validation error for an
incomplete review. draft and pending transitions are allowed while content
is still being prepared.
Legacy pass-only rows have empty contentJson and defenseType: null. They
remain compatible for existing training, but cannot be transitioned to
reviewed as if they were newly structured and reviewed content.
The protected /admin/evidence workspace lets an allowlisted administrator
assemble a narrow evidence bundle, start analysis manually, and review every
generated tactic card beside its citations. The LLM output is always a draft:
it may organize uploaded evidence and operator observations, but it does not
approve tactical truth or publish a playable scenario.
Required server configuration names are:
EVIDENCE_ADMIN_USER_IDS: comma-separated Sites user IDs allowed to use the evidence workspace.EVIDENCE_LLM_ENDPOINT,EVIDENCE_LLM_API_KEY, andEVIDENCE_LLM_MODEL: server-only analyzer configuration. Never expose their values to client code.EVIDENCE_SEARCH_MODELandEVIDENCE_EXTERNAL_ALLOWED_HOSTS: server-only configuration for the opt-in external-source search described below.DB: the logical D1 binding for workflow state, versions, and audit events.EVIDENCE_FILES: the logical R2 binding for original files and extracted text.
External search reuses the existing server-only EVIDENCE_LLM_ENDPOINT and
EVIDENCE_LLM_API_KEY; it has a separate model setting from
EVIDENCE_LLM_MODEL. Set the following non-secret values in local server
environment configuration (for example, an ignored .dev.vars file):
EVIDENCE_SEARCH_MODEL=gpt-5-mini
EVIDENCE_EXTERNAL_ALLOWED_HOSTS=1:official.example,2:coach.example.edu,3:research.example.orgEach allowed-host entry is trust-tier:hostname; tier 1 is the highest
trust tier and the hostname is matched by the server policy. Keep
EVIDENCE_LLM_API_KEY only in local secret environment configuration and
never commit it. If either external-search setting is absent, only external
search is unavailable: direct evidence, analysis, and review continue to
work.
For Sites/Cloudflare, provision EVIDENCE_SEARCH_MODEL and
EVIDENCE_EXTERNAL_ALLOWED_HOSTS as server-side environment variables on the
same deployment that already has EVIDENCE_LLM_ENDPOINT and the secret
EVIDENCE_LLM_API_KEY. Do not place any of these values in client-side build
variables. Apply the D1 migrations before routing traffic to a release that
reads the external-search tables; retain the existing DB and
EVIDENCE_FILES bindings.
An operator follows this explicit flow: open or create a bundle → add direct evidence → start an external search deliberately → inspect and select at most five candidates → import the selected sources → confirm the final inventory → analyze → complete human card review. Search candidates that are not selected are never imported or analyzed, and an operator may skip search and use only direct evidence.
Evidence files may be PDF, TXT, Markdown, or .markdown, with an exact maximum
of 20 MiB per file. Text must be UTF-8. PDF extraction supports text layers;
image-only scans are retained but marked as requiring OCR, which this MVP does
not perform. Video evidence is recorded as an HTTPS URL plus an increasing
start/end timecode and a human observation; the video itself is not copied.
Use the workflow in this order:
- Name one training purpose and add traceable source files or video ranges.
- Review the complete inventory and explicitly confirm that only those sources may be analyzed.
- Start analysis manually. A failed job can be retried without duplicating a completed stage.
- Compare every action and reason with its cited excerpt or timecode. Low confidence, unresolved conflicts, missing citations, and stale bundle versions cannot be approved.
- Record owner review. An approved card can create only an unreviewed scenario draft and must still pass the existing source, animation timeline, and explanation review gates before publication.
After evidence analysis produces a tactic card, complete its animation in this order:
- Analyze a confirmed evidence bundle.
- Open one tactic card and generate its animation draft.
- Review the
관찰,선택,결과, and기억stages in sequence. - Drag estimated players or the ball to the corrected pitch positions.
- Save, run the full preview, and then complete the tactical, motion, and explanation checks.
- Record the owner review only after all three animation checks pass.
- Create an unreviewed scenario draft, then complete the existing source, timeline, and explanation publication review.
OpenAI produces only the first animation draft. Regenerating or changing its
spatial or narrative content clears the three animation checks. Neither a
tactic card nor a scenario becomes public automatically: a human owner must
approve the card, and the derived scenario starts with every publication flag
set to false.
Changing or removing evidence advances the authoritative bundle version and invalidates prior analysis and approval. Deletion is blocked while cards or scenario drafts still reference a source, and the admin UI shows that impact before confirmation. Original filenames are display metadata only; storage uses opaque keys and authenticated downloads.
Anonymous team-room return keys remain a separate device credential. If a participant loses that key, their anonymous progress cannot be recovered; the evidence administration workflow does not change this rule.
Generate a migration after changing the Drizzle schema:
npm run db:generateInspect the generated SQL before committing. Keep changes additive so existing D1 data is preserved.
To use the protected Coach Desk on localhost, add these ignored local-only
settings to .env.local:
EVIDENCE_ADMIN_USER_IDS=local-admin
EVIDENCE_LOCAL_AUTH_ENABLED=1
EVIDENCE_LOCAL_AUTH_SECRET=<a-long-random-local-secret>Then open /admin/evidence and choose 로컬 코치로 입장. The development
session is stored in an HttpOnly cookie. This route remains unavailable unless
the server is in development mode, the request host is loopback, the feature is
explicitly enabled, and local-admin is allowlisted. Deployed Sites continue
to use ChatGPT sign-in.
npm install
npm run dev
npm test
npm run lintThe test suite uses local example fixtures to exercise the UI and review workflow. Those fixtures are never inserted into D1 and are not tactical recommendations. They only verify that all six defense labels and the training interaction can render safely without publishing content.