From 808af4ebfb2c7757b39b8faa1c8520f8fc71854f Mon Sep 17 00:00:00 2001 From: "Michal@MacBook" Date: Tue, 20 Jan 2026 16:00:28 +0100 Subject: [PATCH] Sync 9 common files from main branch --- .devcontainer/devcontainer.json | 2 +- .vscode/mcp.json | 4 +++ PRD.md | 48 ++++++++++++++++++++++----- backend/activity-service/.env.example | 2 +- backend/pet-service/.env.example | 2 +- challenges/challenge-08/README.md | 3 -- infra/main.bicep | 40 +++++++++++++++++++++- solutions/challenge-08/README.md | 2 +- specs/platform/ARCHITECTURE.md | 8 +++-- 9 files changed, 93 insertions(+), 18 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 7ca66ad..bcab749 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,7 +2,7 @@ "name": "MicroHack-GitHub", "image": "mcr.microsoft.com/devcontainers/python:3.12-bookworm", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", - "postCreateCommand": "az version && (curl -LsSf https://astral.sh/uv/install.sh | sh -s -- --yes) && /bin/bash ./.devcontainer/setup_ports.sh", + "postCreateCommand": "az version && (curl -LsSf https://astral.sh/uv/install.sh | sh) && uvx --version && /bin/bash ./.devcontainer/setup_ports.sh", "forwardPorts": [ 3000, 8010, diff --git a/.vscode/mcp.json b/.vscode/mcp.json index bd5f8fc..5e6284e 100644 --- a/.vscode/mcp.json +++ b/.vscode/mcp.json @@ -6,6 +6,10 @@ "args": [ "mcp-server-fetch" ] + }, + "GitHub-MCP": { + "url": "https://api.githubcopilot.com/mcp", + "type": "http" } }, "inputs": [] diff --git a/PRD.md b/PRD.md index 04bfc38..545b46f 100644 --- a/PRD.md +++ b/PRD.md @@ -3,7 +3,7 @@ > Duplicate into your repository's `docs/` folder. Keep narratives concise and traceable to measurable outcomes. ## 1. Metadata -- **Product / Feature Name**: PetPal Frontend, Pet Service, Activity Service +- **Product / Feature Name**: PetPal Frontend, Pet Service, Activity Service, Accessory Service - **Author(s)**: GitHub Copilot - **Date**: 2025-11-18 - **Revision**: v1.0 @@ -16,21 +16,26 @@ PetPal needs a cohesive web experience that lets pet owners view, edit, and moni ## 3. Goals & Non-Goals | Goals | Non-Goals | | --- | --- | -| Unified dashboard for viewing and editing pet profiles plus recent activities. | Full e-commerce checkout, payments, or order management. | -| Reliable CRUD APIs for pets and activities with Cosmos DB persistence. | Native mobile apps; responsive web is sufficient. | -| Capture meaningful telemetry for pet creation and activity logging. | Advanced analytics pipelines or ML-driven recommendations. | +| Unified dashboard for viewing and editing pet profiles plus recent activities and accessories. | Full e-commerce checkout, payments, or order management. | +| Reliable CRUD APIs for pets, activities, and accessories with Cosmos DB persistence. | Native mobile apps; responsive web is sufficient. | +| Capture meaningful telemetry for pet creation, activity logging, and accessory interactions. | Advanced analytics pipelines or ML-driven recommendations. | +| Provide simple, low-friction validation of accessory demand before deeper investment. | Complex inventory, warehouse, or supplier integrations. | ## 4. Success Metrics - Reduce average time to create a pet and first activity to <3 minutes (measured via frontend telemetry funnel tracked in Application Insights). - Achieve P95 latency <500 ms for write operations across services under emulator load tests (measured by load-test scripts owned by the backend team). - Reach 70% engagement where daily-active users interact with both pets and activities modules (measured via frontend instrumentation dashboards maintained by product analytics). +- Within 60 days of launch, at least 40% of weekly-active users view or search accessories in a session. +- Maintain accessory catalog coverage for at least three common categories per pet type (e.g., food, enrichment, care) with no more than 10% of active items in a low-stock state. +- Reduce median time to identify and resolve low-stock accessory items to <2 working days (from first low-stock signal to being back in a healthy range). ## 5. Users & Personas | Persona | Needs | Success Criteria | | --- | --- | --- | -| Household Pet Owner | Quick overview of pet health, edit details, log walks/feeds. | Can add a new pet and log an activity without errors in <6 minutes. | -| Caretaker/Staff | Manage multiple pets, filter by status or date, ensure compliance logs. | Finds any pet or activity within 3 search/filter interactions. | -| Clinic/Trainer Partner | Record structured vet/training visits tied to specific pets. | Logs specialized activities with notes and timestamps. | +| Household Pet Owner | Quick overview of pet health, edit details, log walks/feeds, discover useful accessories. | Can add a new pet, log an activity, and view at least one relevant accessory suggestion without errors in <6 minutes. | +| Caretaker/Staff | Manage multiple pets, filter by status or date, ensure compliance logs, monitor accessory stock. | Finds any pet, activity, or accessory within 3 search/filter interactions and can identify low-stock items in <1 minute. | +| Clinic/Trainer Partner | Record structured vet/training visits tied to specific pets and recommend appropriate accessories. | Logs specialized activities with notes and timestamps and can reference a small, curated list of related accessories per pet profile. | +| Admin / Inventory Owner | Maintain a simple, accurate catalog of accessories and stock levels. | Can review, adjust, or retire accessory records in bulk without data inconsistencies being reported by staff or caretakers. ## 6. Assumptions & Constraints - Azure Cosmos DB (NoSQL API) is the authoritative store; emulator is used locally with same schema. @@ -44,6 +49,9 @@ PetPal needs a cohesive web experience that lets pet owners view, edit, and moni | Create pet | User is on dashboard | User submits valid pet form | Pet appears on card list with health metrics | `backend/pet-service/test_api.py` | | Filter activities | Activities exist for multiple pets | User filters by pet and date | List shows only matching activities in reverse chronological order | Add test to `backend/activity-service` (TBD) | | Log activity from pet view | Pet detail drawer open | User submits activity modal | Activity timeline refreshes with new entry and success toast | Cypress/UI smoke test (future) | +| Browse accessories | User is on the main dashboard with accessories enabled | User opens the accessories view and filters by type | The list shows only matching accessories with name, type, price, and stock indicators, and pagination where needed | Backend + frontend tests (future) | +| Monitor low stock accessories | Accessories exist with varying stock levels | User applies a "low stock" filter | The system highlights accessories below a defined threshold so that users can quickly identify restocking needs | Backend tests validating filtering logic (future) | +| Maintain accessory catalog | Admin is authenticated with appropriate permissions | Admin creates or updates accessory details | The accessory catalog reflects the change immediately in browse/search results with no duplicate or orphaned entries | Backend tests for create/update/delete (future) | ## 8. Requirements ### Functional @@ -52,9 +60,11 @@ PetPal needs a cohesive web experience that lets pet owners view, edit, and moni 3. Pet Service must expose CRUD endpoints plus search/filter with pagination. 4. Activity Service must support create/read/delete plus filtering by pet, type, and date window. 5. Both services must expose `/health` endpoints that initialize Cosmos resources and report status. +6. Accessory service must support browsing, searching, and basic management of accessories (including type, pricing, and stock level) through backend services. +7. Frontend must present an accessories experience that feels integrated with existing pet and activity workflows (for example, surfacing relevant accessories alongside pet or activity context). ### Non-Functional -- **Performance**: P95 <300 ms for reads, <500 ms for writes at workshop scale across pets and activities; monitor RU usage. +- **Performance**: P95 <300 ms for reads, <500 ms for writes at workshop scale across pets, activities, and accessories; monitor RU usage. - **Security/Privacy**: Enforce HTTPS, store secrets in environment variables or managed identity, validate payloads server-side. - **Observability**: Structured logs include request id, RU charge, and HTTP status; propagate `traceparent` header end-to-end. - **Accessibility**: Frontend components meet WCAG 2.1 AA keyboard and contrast requirements. @@ -63,6 +73,28 @@ PetPal needs a cohesive web experience that lets pet owners view, edit, and moni - Wireframes live in `solutions/challenge-06/docs/app-full.png`; they show the dashboard layout referenced above. - Primary journey: dashboard → create pet → view pet detail → log activity → confirm toast → updated timeline. - Secondary journey: use filters/search on dashboard to locate specific pets/activities, leveraging query parameters to the services. +- Accessories journey: dashboard → open accessories view (or accessory panel) → browse and filter accessories → view accessory details → note items to acquire or restock. +- Cross-sell journey: from a pet or activity context, surface a small set of relevant accessories (for example, harnesses for dogs with frequent outdoor activities) that users can review without leaving their current flow. + +## 9a. Accessories + +### Problem & Opportunity +- Today, PetPal focuses on pets and activities but does not help users discover, organize, or reason about accessories that support pet care (toys, food, collars, bedding, grooming, etc.). +- Caretakers and staff often rely on external tools or memory to decide what accessories to use or restock, which leads to inconsistent experiences and missed engagement opportunities. +- By introducing a lightweight accessories capability, PetPal can increase stickiness (more time spent in the product), support operational tasks like stock monitoring, and lay the groundwork for future monetization without committing to full commerce flows. + +### Primary Roles & Needs +- **Household Pet Owner**: Wants to quickly see which accessories are relevant for each pet (by type or activity) and to understand basic details like size, price, and whether an item is available. +- **Caretaker/Staff**: Wants a fast way to scan all accessories, filter by type or low-stock status, and ensure they have appropriate items on hand for upcoming activities or stays. +- **Admin / Inventory Owner**: Wants to maintain a simple, accurate catalog of accessories (create, update, retire) and quickly detect low-stock items so they can trigger restocking actions. + +### User Stories +- As a household pet owner, I want to browse accessories by type and basic filters so that I can quickly find items that are relevant to my pet without having to leave PetPal. +- As a caretaker/staff member, I want to search and filter accessories (by type, name, and low-stock state) so that I can quickly identify what is available and what needs attention. +- As a user viewing a pet profile, I want to see a small set of suggested accessories tied to that pet’s characteristics or recent activities so that I can discover useful items in context. +- As an admin/inventory owner, I want to create, update, and retire accessories so that the catalog stays accurate and users do not see outdated or incorrect options. +- As an admin/inventory owner, I want to monitor low-stock accessories in a dedicated view so that I can trigger restocking before items become unavailable. +- As a product owner, I want to soft-launch accessories to a subset of users or as an optional dashboard panel so that we can validate demand and interaction patterns before investing in advanced features. ## 10. Dependencies - Internal: Pet Service (FastAPI), Activity Service (FastAPI), shared Cosmos DB account/emulator, infra scripts in `start.sh`. diff --git a/backend/activity-service/.env.example b/backend/activity-service/.env.example index ef69452..dd789a3 100644 --- a/backend/activity-service/.env.example +++ b/backend/activity-service/.env.example @@ -8,7 +8,7 @@ COSMOS_CONTAINER_NAME=activities # Application Configuration -APP_NAME=Activity Service +APP_NAME="Activity Service" APP_VERSION=1.0.0 DEBUG=True LOG_LEVEL=INFO diff --git a/backend/pet-service/.env.example b/backend/pet-service/.env.example index 610895c..9207165 100644 --- a/backend/pet-service/.env.example +++ b/backend/pet-service/.env.example @@ -12,7 +12,7 @@ COSMOS_CONTAINER_NAME=pets # For HTTPS with self-signed cert, set: # COSMOS_EMULATOR_DISABLE_SSL_VERIFY=true -APP_NAME=Pets Service +APP_NAME="Pets Service" APP_VERSION=1.0.0 DEBUG=True LOG_LEVEL=INFO \ No newline at end of file diff --git a/challenges/challenge-08/README.md b/challenges/challenge-08/README.md index b60b0e7..3a34711 100644 --- a/challenges/challenge-08/README.md +++ b/challenges/challenge-08/README.md @@ -82,9 +82,6 @@ Deploy the PetPal microservices to Azure using Infrastructure as Code (IaC). Thi Example of provisioned services in Azure Portal: ![Azure Portal Container Apps](../../solutions/challenge-08/docs/infra-provisioned.jpg) -3. **Test the Application**: - - Access frontend URL from deployment outputs - - Check Container Apps logs for errors ## Success Criteria diff --git a/infra/main.bicep b/infra/main.bicep index 735006a..4a910a4 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -140,6 +140,20 @@ module activityService 'container-app.activity-service.bicep' = { } } +module accessoryService 'container-app.accessory-service.bicep' = { + name: 'accessory-service-deployment' + params: { + name: '${resourcePrefix}-accessory-service' + location: location + containerAppEnvironmentId: containerAppEnvironment.outputs.environmentId + cosmosEndpoint: cosmosDb.outputs.endpoint + cosmosDatabaseName: accessoryServiceCosmos.databaseName + cosmosContainerName: accessoryServiceCosmos.containerName + acrName: acrName + acrLoginServer: containerRegistry.outputs.loginServer + } +} + resource cosmosAccountExisting 'Microsoft.DocumentDB/databaseAccounts@2025-04-15' existing = { name: cosmosAccountName } @@ -164,6 +178,16 @@ resource activityServiceCosmosDataRole 'Microsoft.DocumentDB/databaseAccounts/sq } } +resource accessoryServiceCosmosDataRole 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2025-04-15' = { + name: guid(resourceGroup().id, 'accessory-service-cosmos-data') + parent: cosmosAccountExisting + properties: { + roleDefinitionId: cosmosDataPlaneRoleDefinitionId + principalId: accessoryService.outputs.identityPrincipalId + scope: cosmosAccountResourceId + } +} + resource petServiceCosmosControlRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(resourceGroup().id, 'pet-service-cosmos-control') scope: cosmosAccountExisting @@ -184,6 +208,16 @@ resource activityServiceCosmosControlRole 'Microsoft.Authorization/roleAssignmen } } +resource accessoryServiceCosmosControlRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(resourceGroup().id, 'accessory-service-cosmos-control') + scope: cosmosAccountExisting + properties: { + roleDefinitionId: cosmosControlPlaneRoleDefinitionId + principalId: accessoryService.outputs.identityPrincipalId + principalType: 'ServicePrincipal' + } +} + module frontend 'container-app.frontend.bicep' = { name: 'frontend-deployment' params: { @@ -193,7 +227,7 @@ module frontend 'container-app.frontend.bicep' = { frontendImage: frontendImage petServiceUrl: petService.outputs.fqdn activityServiceUrl: activityService.outputs.fqdn - accessoryServiceUrl: '' + accessoryServiceUrl: accessoryService.outputs.fqdn } } @@ -260,6 +294,10 @@ output activityServiceUrl string = activityService.outputs.fqdn output activityServiceName string = activityService.outputs.name output activityServiceManagedIdentityClientId string = activityService.outputs.identityClientId +output accessoryServiceUrl string = accessoryService.outputs.fqdn +output accessoryServiceName string = accessoryService.outputs.name +output accessoryServiceManagedIdentityClientId string = accessoryService.outputs.identityClientId + output frontendUrl string = frontend.outputs.fqdn output githubManagedIdentityClientId string = githubManagedIdentityClientId == null ? '' diff --git a/solutions/challenge-08/README.md b/solutions/challenge-08/README.md index dc55b2c..4c80ffe 100644 --- a/solutions/challenge-08/README.md +++ b/solutions/challenge-08/README.md @@ -328,7 +328,7 @@ azd version # Login to Azure az login -azd auth login +azd auth login --use-device-code # Set subscription (if you have multiple) az account set --subscription diff --git a/specs/platform/ARCHITECTURE.md b/specs/platform/ARCHITECTURE.md index 1b64196..60c14fb 100644 --- a/specs/platform/ARCHITECTURE.md +++ b/specs/platform/ARCHITECTURE.md @@ -26,13 +26,16 @@ graph TB Frontend[Frontend App] PetService[Pet Service] ActivityService[Activity Service] + AccessoryService[Accessory Service] DB[Azure Cosmos DB] User -->|Uses| Frontend Frontend -->|API Calls| PetService Frontend -->|API Calls| ActivityService + Frontend -->|API Calls| AccessoryService PetService -->|Persists data to| DB ActivityService -->|Persists data to| DB + AccessoryService -->|Persists data to| DB ``` ### Container / Service View @@ -42,11 +45,12 @@ graph TB | **Frontend** | User interface for dashboard, pet management, and activity logging. | React | Azure Container Apps | Frontend Team | | **Pet Service** | Manages pet profiles, metadata, and CRUD operations. | Python (FastAPI) | Azure Container Apps | Backend Team | | **Activity Service** | Manages activity logs, timelines, and historical data. | Python (FastAPI) | Azure Container Apps | Backend Team | +| **Accessory Service** | Manages pet accessories, inventory, and CRUD operations. | Python (FastAPI) | Azure Container Apps | Backend Team | | **Database** | Centralized NoSQL store for all pet and activity data. | Azure Cosmos DB (NoSQL) | Azure Cosmos DB Serverless | Platform Team | ### Data Flow 1. **User Interaction**: User performs an action (e.g., "Create Pet") on the Frontend. -2. **API Request**: Frontend sends an authenticated HTTPS request to the relevant service (Pet or Activity Service). +2. **API Request**: Frontend sends an authenticated HTTPS request to the relevant service (Pet, Activity, or Accessory Service). 3. **Persistence**: Service validates the request and writes/reads from Azure Cosmos DB. 4. **Response**: Service returns JSON response to Frontend; Frontend updates UI. @@ -83,4 +87,4 @@ graph TB ## Decision References - **ADR-001**: Use of Azure Cosmos DB for schema flexibility and scalability. -- **ADR-002**: Microservices architecture (Pet vs. Activity) to allow independent scaling and lifecycle management. +- **ADR-002**: Microservices architecture (Pet vs. Activity vs. Accessory) to allow independent scaling and lifecycle management.