Epic 5: Complete AI Council Generator - Navigation, Search, Themes#6
Merged
Conversation
- Initialize CDK v2 TypeScript app with strict mode - Create LocalGovDrupalStack with deploymentMode and councilTheme props - Add project structure: cdk/, docker/, drupal/, tests/ - Add 5 unit tests for stack synthesis and configuration - Configure Jest, .gitignore, README documentation - Generate initial CloudFormation template via cdk synth Story: 1-1-project-scaffolding-cdk-setup Epic: 1 - LocalGov Drupal Infrastructure Foundation
Story 1-2: LocalGov Drupal Container Image Implements multi-stage Docker build for LocalGov Drupal on AWS Fargate: - PHP 8.2-fpm-alpine with required extensions (gd, pdo_mysql, opcache, etc.) - Nginx configured for Drupal with 120s timeout for AI operations - LocalGov Drupal 3.x with Drush 12 and AWS SDK - Supervisord for PHP-FPM + Nginx process management - Environment variable configuration for database and settings - Health check endpoint for ALB integration Code review fixes applied: - Fixed nginx user directive (nginx → www-data) - Removed invalid nginx env var fastcgi_params - Added www-data user creation in Dockerfile Image size: 220MB (under 1GB requirement)
Story 1-3: Container Build & Publish Pipeline Implements automated Docker container builds for LocalGov Drupal: - GitHub Actions workflow triggered on push to main - Path filter for docker/**, drupal/**, .dockerignore changes - docker/build-push-action with ghcr.io registry - SHA and latest tagging via docker/metadata-action - GHA cache for faster builds - workflow_dispatch for manual triggers Image published to: ghcr.io/[org]/localgov-drupal
Implement CDK networking construct (Story 1-4) with least-privilege security groups: - ALB SG: allows inbound 443/80 from 0.0.0.0/0, outbound to Fargate only - Fargate SG: allows inbound 80 from ALB, outbound to AWS APIs - Aurora SG: allows inbound 3306 from Fargate only - EFS SG: allows inbound 2049 from Fargate only Uses default VPC lookup per ADR-002 to avoid NAT Gateway costs.
Implements DatabaseConstruct for LocalGov Drupal with: - Aurora Serverless v2 MySQL 8.0 (VER_3_04_0) - Scale-to-zero capability (0.5-2 ACU) - Secrets Manager for credentials (username: drupal) - Storage encryption enabled - Default database: drupal - Exports cluster, secret, and clusterEndpoint Includes 3 new tests for Aurora cluster, Secrets Manager, and writer instance. All 10 tests passing.
Implements StorageConstruct for LocalGov Drupal with: - EFS file system with encryption at rest - generalPurpose performance mode, bursting throughput - AFTER_30_DAYS lifecycle policy for cost optimization - Access point at /drupal-files with www-data POSIX user (UID/GID 33) - Exports fileSystem, accessPoint, and fileSystemId Includes 3 new tests for EFS file system, access point, and mount targets. All 13 tests passing.
Implements compute layer for LocalGov Drupal on AWS: - ECS cluster with Container Insights - Fargate task definition (0.5 vCPU, 1GB memory) - Container with EFS volume mount, env vars, secrets - IAM roles for Bedrock, Polly, Translate, Rekognition, Textract - Internet-facing ALB with HTTP listener - Health checks on / path - Circuit breaker with rollback enabled - ECS Exec enabled in development mode All 18 tests passing.
Implement automatic Drupal initialization on first deployment with CloudFormation WaitCondition signaling for deployment coordination. Changes: - docker/scripts/init-drupal.sh: Complete init script with database wait loop, drush site:install, config import, and CloudFormation signaling - docker/config/nginx.conf: Added /init-status endpoints for progress monitoring with HTML and JSON status pages - cdk/lib/constructs/compute.ts: Added waitConditionUrl prop to pass WaitCondition URL to container as WAIT_CONDITION_URL env var - cdk/lib/localgov-drupal-stack.ts: Added CfnWaitConditionHandle and CfnWaitCondition with 15 minute timeout - cdk/test/localgov-drupal-stack.test.ts: Added 3 tests for WaitCondition resources and env variable All 21 tests pass. Story: 1-8-drupal-init-waitcondition
Add realistic UK council content for demonstration purposes with: Sample Content YAML Files: - services.yml: 16 council services (Waste, Council Tax, Planning, etc.) - guides.yml: 6 step-by-step guides (planning permission, council tax, etc.) - directories.yml: 12 directory entries (offices, libraries, parks, etc.) - news.yml: 5 news articles (budget, recycling, events, etc.) PHP Import Script (import.php): - Creates content using LocalGov Drupal content types - Falls back to basic page if content types unavailable - Creates taxonomy terms for service categories - Adds main menu navigation items - Idempotent - skips existing content Integration: - init-drupal.sh calls import after site installation - Status page shows "Importing sample content..." at 70% - Dockerfile copies sample-content directory into container Total: 39 content items covering typical UK council services. Story: 1-9-static-sample-content
Implement ndx_demo_banner Drupal module that displays a fixed banner at the top of every page to clearly indicate this is a demonstration site. Features: - Yellow/black striped pattern (#ffdd00/#0b0c0c) using GOV.UK colors - 44px height fixed at viewport top (z-index: 1001) - Dynamic council name from COUNCIL_NAME env var (default: Westbridge Council) - Text: "DEMONSTRATION SITE - [Council Name] is a fictional council" - Cannot be dismissed by users (no close button, fixed position) - Admin toolbar offset handling for Drupal backend Accessibility: - role="complementary" with aria-label for screen readers - High contrast mode support (solid background) - Reduced motion preference (removes stripes) - Print styles hide banner Integration: - Module enabled via drush pm:enable in init-drupal.sh - Enabled during fresh install flow after sample content import All 21 CDK tests pass. Story: 1.10 DEMO Banner Module
Implement ndx_welcome Drupal module that displays a welcoming orientation experience on the admin dashboard for first-time users. Features: - Council name prominently displayed (32px heading with blue accent) - "Welcome to LocalGov Drupal" subtitle - Green "Start Here" badge with call-to-action - Quick links grid: Manage Content, Media Library, View Site, Docs - Card-style layout with hover and focus states Accessibility: - role="region" with aria-labelledby for semantic structure - Yellow focus rings (#ffdd00) following GOV.UK patterns - External links announce "(opens in new tab)" for screen readers - Print-friendly styles Technical: - Custom block plugin (WelcomeBlock.php) - Install hook places block on /admin/content page - Council name from COUNCIL_NAME env var (default: Westbridge Council) - GOV.UK-inspired styling with responsive grid All 21 CDK tests pass. Story: 1.11 First Login Welcome Experience
Story 1.12 - CloudFormation Outputs & Quick Create - Add DrupalUrl output (ALB DNS name with http:// prefix) - Add AdminUsername output (static "admin" value) - Add AdminPassword output (dynamic Secrets Manager reference) - Add CloudWatchLogsUrl output (console URL with encoded log group) - Add StackDescription output for stack identification - Expose logGroup from compute construct for output reference - Add 4 tests for output existence (25 tests total now pass) - Mark Epic 1 as done (all 12 stories complete) Enables one-click Quick Create deployment once template is uploaded to S3.
Story 2.1 - Portal Scenario Landing Page - Add localgov-drupal.njk scenario page using existing template - Add comprehensive scenario data to scenarios.yaml - Include 8 AWS services, deployment config, success metrics - Set as order 1, shift existing scenarios to 2-7 - Build verified: 97 pages including new scenario - Marks beginning of Epic 2 (Guided Walkthrough Experience)
Story 2.2 - Deployment Progress Component - Add deployment-progress.njk component with real-time status tracking - Add deployment-progress.js with demo mode simulation - Add CSS styles for status badges, progress bar, resource list - Include component in scenario.njk layout - Implement accessibility: aria-live, progressbar role, reduced motion - Add CloudFormation Console deep links for manual monitoring - Demo mode shows realistic 6-phase deployment flow - Build verified: 97 pages including new component
Story 2.3 - Credentials Card Component
- Add credentials-card.njk with URL, username, password fields
- Add credentials-card.js with Clipboard API copy and fallback
- Implement password show/hide toggle with emoji icons
- Add copy success feedback ("Copied!" with green styling)
- URL input editable for users to paste their actual URL
- Login button URL updates dynamically
- Include aria-live announcements for screen readers
- Add responsive CSS for mobile devices
- Build verified: 97 pages, 186 assets
Implement basic walkthrough content for LocalGov Drupal scenario: - Landing page with value proposition and prerequisites - Step 1: Getting credentials and logging in - Step 2: Exploring homepage and navigation - Step 3: Editing existing content - Step 4: Understanding the DEMO banner - Step 5: Preparing for cleanup - Completion page with takeaways and next steps Also fixes Yarn PnP compatibility with govuk-eleventy-plugin by switching to node-modules linker and adding missing peer dependencies.
Implements in-CMS guided tour overlay for council officers exploring Drupal admin. Provides 8-step tour covering toolbar, content, structure, appearance, configuration, and reports sections. Features: - Spotlight highlighting of target elements with yellow focus ring - Modal positioning relative to targets with viewport constraints - Focus trap within modal for keyboard accessibility - Keyboard navigation (Tab cycles, Escape closes) - Progress persistence via localStorage with auto-resume - Auto-trigger on first login - Integration with ndx_welcome "Take the Guided Tour" button - Scroll-into-view for off-screen targets WCAG 2.2 AA compliant: - 3px yellow focus rings (#ffdd00) - 44x44px minimum touch targets - aria-modal, aria-labelledby, aria-describedby attributes - prefers-reduced-motion support Code review fixes applied: - Null checks for event listeners - CSS custom properties for z-index maintainability - Data attribute trigger pattern vs inline onclick
…sistence (Story 2-6) - Add progress-bar.njk component with ARIA attributes - Add step-checklist.njk with completed/current/upcoming visual states - Add walkthrough-progress.njk sidebar with reset modal - Add progress.css with GOV.UK Design System patterns - Extend walkthrough.js with progress sidebar, reset modal focus trap - Integrate progress sidebar into walkthrough layout WCAG 2.2 AA compliant: aria-live, focus rings, reduced motion support
- Add drupal-screenshots.spec.ts for automated Drupal screenshot capture - Support public pages (homepage, services, guides, news) and admin pages - Environment variable configuration for DRUPAL_URL, DRUPAL_USER, DRUPAL_PASS - Automatic manifest generation tracking screenshot metadata - Integrate localgov-drupal scenario with check-screenshots.js validation - Add test:drupal-screenshots npm script Tests skip gracefully when environment variables not set
- Add comprehensive documentation-standards.md with 6 major sections - Create walkthrough-step-template.md with placeholder structure - Create walkthrough-step-example.md with LocalGov Drupal content - Include terminology glossary (24 terms across 4 categories) - Define screenshot naming convention aligned with Story 2-7 - Document WCAG 2.2 AA accessibility requirements - Add Drupal overlay content standards with step length limits
Implements PDF evidence pack generation for council officers to share deployment outcomes with stakeholders and committees. Features: - PDF generator using jsPDF with GOV.UK styling (green/blue headers) - Evidence pack form with evaluator details, deployment info, observations - Screenshot upload with base64 embedding in PDF - Session data pre-population from localStorage - Loading states and success/error feedback - "Generate Evidence Pack" button on walkthrough complete page Files created: - src/lib/pdf-generator.js - EvidencePackGenerator class - src/_includes/components/evidence-pack-form.njk - Form component - src/walkthroughs/localgov-drupal/evidence-pack.njk - Evidence pack page Files modified: - package.json - Added jsPDF ^2.5.2 - eleventy.config.js - Added lib directory passthrough - complete.njk - Added Evidence Pack button section Story 2-9 satisfies acceptance criteria: - PDF contains scenario name, date, deployment success, Drupal URL - AWS region and estimated cost included - Screenshot sections (homepage, admin dashboard) - Space for notes/observations - GOV.UK document patterns applied - Form pre-populated with session data - PDF downloads immediately on generation
Add reusable cleanup-instructions.njk component with: - Step-by-step CloudFormation deletion instructions - Direct us-east-1 console link for stack management - GOV.UK warning text for data loss (RDS, EFS) - Cost confirmation panel affirming charges stop after deletion - 2-hour auto-delete safety net explanation - Troubleshooting sections (DELETE_FAILED, can't find stack) - Screenshot placeholders for future Playwright capture - WCAG 2.2 AA compliant with proper ARIA attributes Integrated component into all 7 scenario complete pages, removing duplicated inline cleanup sections for DRY code. Completes Epic 2: Guided Walkthrough Experience (10 stories)
Implement foundational AWS SDK integration module for Drupal with: - AwsClientFactory with cached clients for Bedrock, Polly, Translate, Rekognition, Textract, and STS (IAM role credentials only) - AwsErrorHandler with user-friendly messages for 12+ AWS error codes - Service interfaces defining contracts for downstream stories - Admin configuration form for AWS region selection - Connection test form using STS GetCallerIdentity - PHP 8.2 strict types, constructor property promotion, match expressions Code review fixes applied: - Corrected Bedrock model IDs to match AWS documentation - Updated Polly voice config to specify engine type per language - Added proper Url class imports in form classes
…mpt templates
Story 3-2: Bedrock Service Integration
- Add BedrockService with generateContent, simplifyText, describeImage methods
- Create PromptTemplateManager for YAML-based prompt loading with {{var}} substitution
- Implement BedrockRateLimiter with exponential backoff and jitter (1s-30s, 3 retries)
- Add BedrockResponseParser with UTF-8 validation and usage extraction
- Create prompt templates for content_generation, simplification, image_description
- Register all services in ndx_aws_ai.services.yml with logger channel
- Add BedrockServiceTest with Prophecy mocking for full coverage
Uses Bedrock Converse API with amazon.nova-pro-v1:0 and amazon.nova-lite-v1:0 models.
Token usage logged for cost tracking via AwsErrorHandler::logOperation().
Add GOV.UK Design System compliant UI components for AI features: - AI Action Button with secondary style and icon support - Loading State with accessible spinner and aria-live - Error State with role="alert" and retry button - Success State with auto-dismiss functionality WCAG 2.2 AA compliance: - 44x44px minimum touch targets - 3px yellow focus ring with 2px offset - prefers-reduced-motion support - High contrast mode support Includes CSS with design tokens, JavaScript behaviours with StateManager utility, and comprehensive README documentation.
Add CKEditor 5 integration for AI-powered content editing features: - AI dropdown button with sparkle icon in editor toolbar - "Help me write..." menu item for AI content generation - "Simplify to plain English" menu item for text simplification - GOV.UK Design System styling with accessibility support - AI service availability check endpoint (/ndx-aws-ai/status) - Graceful degradation when AI services unavailable - WCAG 2.2 AA compliant with keyboard navigation and aria-live Implementation includes: - CKEditor 5 plugin structure (aiToolbar, aiToolbarEditing, aiToolbarUI) - Drupal CKEditor5Plugin PHP class with annotations - AiStatusController for availability checking - CSS styling with GOV.UK colour palette and focus states - isAvailable() method added to BedrockServiceInterface
Implement AI-powered writing assistant for CKEditor integration: - Add AiWritingDialogForm with AJAX content generation - Add PromptHistoryService with private tempstore for user session - Add writing.yml prompt template with LocalGov Drupal tone guidelines - Add ai-writing-handler.js for CKEditor dialog integration - Add ai_writing_dialog library with required dependencies - Add /ndx-aws-ai/write-dialog route for modal form Features: - Content generation via Amazon Bedrock Nova Pro - Editable preview before applying to editor - Insert at cursor position in CKEditor - Last 5 prompts remembered per user session - Full keyboard accessibility with focus trap - Aria-live announcements for screen readers - GOV.UK Design System styling Epic-3: AI-Powered Content Editing
Update simplify.yml prompt to explicitly instruct the model not to wrap HTML output in markdown code fences (```html ... ```). This ensures raw HTML is returned for proper CKEditor rendering.
The simplify feature now uses a direct API call instead of a modal dialog. This fixes the markdown code fence issue by stripping ```html blocks server-side. Changes: - Delete AiSimplifyDialogForm.php (unused modal form) - Delete ai-simplify-handler.js (unused modal JS) - Delete ai-simplify-dialog.css (unused modal CSS) - Remove ai_simplify_dialog library from libraries.yml - Remove simplify_dialog route from routing.yml - Add stripCodeFences() to SimplifyController for clean HTML output
Cleanup: - Remove legacy sample-content directory (replaced by AI generator) - Remove redundant .gitkeep files from directories with content - Add cdk.context.json to .gitignore (account-specific cache) - Update Dockerfile to remove sample-content COPY - Remove import_sample_content() from init-drupal.sh LocalGov Drupal walkthrough: - Add steps 6-8 for Text-to-Speech, cleanup, and evidence collection - Add TTS block configuration to init-drupal.sh - Add optional block config for Listen to Page feature - Add walkthrough screenshots for AWS console and Drupal UI - Update step content and navigation - Rename phase-config.yaml to phaseConfig.yaml Dependency updates: - Update yarn.lock with current dependencies
Add new Step 8 to LocalGov Drupal walkthrough covering the text-to-speech accessibility feature powered by AWS Polly. Changes: - Add step-8.njk for TTS feature walkthrough - Rename cleanup step from step-8 to step-9 - Update totalSteps from 8 to 9 across all step files - Add TTS step to walkthroughs.yaml metadata - Capture TTS player screenshots from live Drupal instance - Enhance Playwright tests for TTS screenshot capture The new step explains: - What the Listen to Page feature does - Which content types have TTS (services, guides, news) - Player controls (language, play/pause/stop, progress, speed) - How AWS Polly integration works - Accessibility benefits for different user groups
Add configure_translation_block function to automatically place the content translation block in the content_top region during Drupal initialization. Block configuration: - Plugin: ndx_content_translation - Region: content_top (weight 1, after TTS block) - Visibility: guides, news, services pages - Settings: priority languages enabled, search disabled, remember preference enabled Also captured translation widget screenshots for walkthrough.
…uto-detect AWS Translate requires the comprehend:DetectDominantLanguage IAM permission when using SourceLanguageCode='auto' to auto-detect the source language. Without this permission, translation requests fail with AccessDeniedException.
The ContentTranslationController was calling getSourceLanguage() and getTranslatedText() methods that didn't exist on the TranslationResult class. Added these getter methods for compatibility.
The CSS rule `display: flex` was overriding the `hidden` attribute on the loading indicator element. Changed to use `:not([hidden])` selector so the flex layout only applies when the element is not hidden.
Add new step 9 covering the content translation feature powered by AWS Translate. Move cleanup step from 9 to 10 and update totalSteps across all walkthrough files. - Create step-9.njk for translation feature with language grid, instructions, accessibility benefits table, and AWS service card - Create step-10.njk (moved cleanup content from former step 9) - Update totalSteps from 9 to 10 in step-1 through step-8 - Update walkthroughs.yaml: totalSteps, duration (33 min), add step
Add step 7 covering the AI-powered PDF to Web Converter feature that uses Amazon Textract for document extraction and Amazon Bedrock for content structuring. Bumps subsequent steps (7→8 through 10→11). Changes: - Create new step-7.njk for PDF to Web Converter feature - Renumber steps 7-10 to 8-11 (DEMO banner, TTS, Translation, Cleanup) - Update totalSteps from 10 to 11 in all step files - Update walkthroughs.yaml with new step and duration (37 minutes) - Add pdf-converter-form-desktop.png screenshot
- Add AltTextController with API endpoints for generating alt-text - Add alt-text-generator.js to handle file uploads and API calls - Add form alters for media image add/edit forms - Add Generate with AI button on media edit forms - Attach library to media library upload forms - This fixes the timing issue where form validation prevented presave
- Add setTimeout delay to ensure DOM is fully updated after AJAX - Look for alt field in form context if not in wrapper - Track fid value changes to prevent duplicate processing - Add logging for debugging
The Drupal behavior was being attached after AJAX completes, but the MutationObserver never saw the initial file ID value. Now checkAndGenerate() runs immediately when the behavior attaches, catching files that were already uploaded.
The media_library image style converts images to WebP format, but GD was compiled without WebP support causing 500 errors on thumbnail generation. Added libwebp-dev to build dependencies and --with-webp flag to GD configuration in both builder and runtime stages.
Add new walkthrough step demonstrating the AI-powered auto alt-text generation feature. This step shows how Amazon Nova vision model automatically generates WCAG-compliant image descriptions when uploading images to the Media Library. Changes: - Insert new step-7.njk for Auto Alt-Text Generation after step 6 - Rename existing steps 7-11 to 8-12 (PDF converter, DEMO banner, Listen to Page, Translate, Cleanup) - Update totalSteps from 11 to 12 across all walkthrough files - Add screenshots showing the feature in action - Update walkthroughs.yaml with new step and 40-minute duration
Build always runs for validation, but push only happens on main. IaC updated to pull :latest tag which main branch publishes.
25b6992 to
665d111
Compare
1 task
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.
Epic 5: AI Council Generator Module
This PR completes the AI-powered council generation system for LocalGov Drupal on AWS, addressing critical issues discovered during testing.
Context
The AI-Enhanced LocalGov Drupal scenario enables UK councils to deploy a fully functional LocalGov Drupal CMS with dynamically generated unique council content. Each deployment creates a fictional UK council with:
Issues Fixed
navigation-landing.yamltemplate not loadedTEMPLATE_FILESarraycontact.yamltemplateNavigationMenuConfiguratorlooked for wrong page typesbuild_search_index()to init scriptinstall_themes()to init script (previous commit)Files Changed
Content Generation:
ContentTemplateManager.php- Addnavigation-landingandcontactto TEMPLATE_FILEScontact.yaml(NEW) - Template for council contact pageNavigation:
NavigationMenuConfigurator.php- FixgetMainMenuItems()to find correct landing pagesInit Script:
init-drupal.sh- Addbuild_search_index()function for Search API indexingTest Plan
drush localgov:generate-council --forcetheme=localgov_scarfolk)Related PRD Requirements
From
_bmad-output/prd.md:PR: Draft for review before merge
Epic: 5 - AI Council Generator Module
Stories: 5.3 Content Templates, 5.9 Navigation Menu Configuration