✨ Tiger Portal — transcript upload, per-user dashboard history, SWA login#147
Draft
yaqi-lyu wants to merge 8 commits into
Draft
✨ Tiger Portal — transcript upload, per-user dashboard history, SWA login#147yaqi-lyu wants to merge 8 commits into
yaqi-lyu wants to merge 8 commits into
Conversation
- Untrack .claude/launch.json (local editor artifact) and gitignore it. - Remove @azure/storage-blob/@azure/storage-queue from azure-function: the code using them moved to portal-api, so they were dead deps. This reverts azure-function/package-lock.json back to master (removes ~230 lines of lockfile churn from the PR). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- node: import protocol + optional chaining + import-type (mechanical). - Suppress intentional control-char filename regex and the drag-drop static-element a11y rule, each with a documented reason. - "Transcript file" label → <p> (the dropzone input carries its own label). Left untouched: pre-existing noUnusedVariables in ProcessTranscriptQueue.js and projectSetup.js (predate this PR) and idiomatic non-null assertions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds AC #2/#4 from #137 — a second submission mode alongside file upload. - portal: UploadView gains an "Upload transcript | Paste meeting link" toggle; SubmissionClient.submitLink() POSTs JSON to /api/v1/meetings. - portal-api: SubmitMeetingLink (POST /api/v1/meetings) validates the link format (parses context/Oid - no Graph call), writes the shared history record, and enqueues a `meetingLink` message. Stays Graph-free. - azure-function: queueMessage normalizes/deduplicates/env-maps `meetingLink`. - processor: downloadFromMeetingLink.js resolves joinUrl to the organizer's onlineMeetings, latest transcript, VTT - in the Job (which already has Graph creds). Reuses validateDownloadedVtt + detectVttSpeakers. - entrypoint.sh: PORTAL_SUBMISSION covers upload + meetingLink (shared history write-back, Logic App notifications suppressed). Webhook untouched. Authorization: any authenticated SSW-tenant user with a valid link can process it; participant-level restriction is a future tightening. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removes deploy-portal-api-test.yml and deploy-portal-swa-test.yml. The existing func deploy job and manual runs cover deployment; these can be re-added later. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #137
Summary
Adds the Parrot portal — a self-serve entry point where an SSW user signs in and either uploads a Teams
.vtttranscript or pastes a Teams meeting link, then gets a generated Tiger dashboard, with a per-user history of their submissions and their status.Both paths flow through the existing queue → Container App Job → dashboard pipeline via a
sourceTypediscriminated union, so no separate processing path was introduced and the automated Graph webhook path is untouched.Architecture
portal/) — React 19 + Vite, styled with Tailwind using the same SSW design tokens as the generated dashboards. Views: Submit (Upload transcript / Paste meeting link) + "My dashboards".portal-api/) — a separate Azure Functions app (func-tiger-portal-*), split from the Graph webhook app so its SWA-only auth boundary never touches the public webhook. Endpoints:POST /api/v1/submissions(file upload),POST /api/v1/meetings(meeting link),GET /api/v1/submissions(per-user history). Stays Graph-free — the meeting-link endpoint only validates the link format; Graph resolution happens in the Job.authLevel: anonymous; the trust boundary is the auto-provisioned "Azure Static Web Apps (Linked)" EasyAuth provider (verified post-deploy).processor/downloadFromMeetingLink.jsruns in the Container App Job (which already has Graph creds), resolving a join URL → organizer'sonlineMeetings→ latest transcript → VTT. The organizer/tenant come from the link's owncontextparam, so a join link alone is sufficient.submissionscontainer (partitioned by/projectName) holds{owner, status, dashboardUrl, …}. The Portal API writes the record on submit; the processor patchesstatus/dashboardUrlon completion.Acceptance criteria (from #137)
.vttuploadmeetingLinkjobuploadedTranscriptjobTriggerProcessing); participant-level restriction is a follow-up. Report-body isolation is intentionally deferred: dashboards remain public shareable URLs so users can send them to attendees.Deploy notes
deployPortal=false(default) — existing deployments are unaffected until explicitly enabled.australiaeastis not one; defaults to East Asia).infra/scripts/portal-post-deploy.sh <env>:Azure Static Web Apps (Linked)EasyAuth provider exists on the Function App — this is what makes the anonymous API safe against forged identity headers..auth/login/aad/callbackredirect URI on the Graph app registration.SSW_TENANT_IDrepo variable — the SWA deploy workflow substitutes it intostaticwebapp.config.jsonand fails loudly if it's missing.TriggerProcessinguses).Testing
portal-api26,azure-function4,portal12,processor(upload + meeting-link) 7 — all green;portalbuilds; bicep compiles;entrypoint.shpassesbash -n.Follow-ups
acceptedrecord" window.🤖 Generated with Claude Code