Skip to content

ci: bump docker/setup-buildx-action from 3 to 4#28

Open
dependabot[bot] wants to merge 155 commits intomainfrom
dependabot/github_actions/docker/setup-buildx-action-4
Open

ci: bump docker/setup-buildx-action from 3 to 4#28
dependabot[bot] wants to merge 155 commits intomainfrom
dependabot/github_actions/docker/setup-buildx-action-4

Conversation

@dependabot
Copy link
Copy Markdown

@dependabot dependabot bot commented on behalf of github Apr 6, 2026

Bumps docker/setup-buildx-action from 3 to 4.

Release notes

Sourced from docker/setup-buildx-action's releases.

v4.0.0

Full Changelog: docker/setup-buildx-action@v3.12.0...v4.0.0

v3.12.0

Full Changelog: docker/setup-buildx-action@v3.11.1...v3.12.0

v3.11.1

Full Changelog: docker/setup-buildx-action@v3.11.0...v3.11.1

v3.11.0

Full Changelog: docker/setup-buildx-action@v3.10.0...v3.11.0

v3.10.0

Full Changelog: docker/setup-buildx-action@v3.9.0...v3.10.0

v3.9.0

Full Changelog: docker/setup-buildx-action@v3.8.0...v3.9.0

v3.8.0

Full Changelog: docker/setup-buildx-action@v3.7.1...v3.8.0

... (truncated)

Commits
  • 4d04d5d Merge pull request #485 from docker/dependabot/npm_and_yarn/docker/actions-to...
  • cd74e05 chore: update generated content
  • eee38ec build(deps): bump @​docker/actions-toolkit from 0.77.0 to 0.79.0
  • 7a83f65 Merge pull request #484 from docker/dependabot/github_actions/docker/setup-qe...
  • a5aa967 Merge pull request #464 from crazy-max/rm-deprecated
  • e73d53f build(deps): bump docker/setup-qemu-action from 3 to 4
  • 28a438e Merge pull request #483 from crazy-max/node24
  • 034e9d3 chore: update generated content
  • b4664d8 remove deprecated inputs/outputs
  • a8257de node 24 as default runtime
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Backend (8th module: oe_ai):
- AI Settings model — per-user API keys for Anthropic/OpenAI/Gemini
- AI Estimate Job — tracks requests with status/timing/token usage
- AI Client — async httpx calls to 3 providers (no SDK deps)
  - Anthropic Claude (with vision support)
  - OpenAI GPT-4 (with vision)
  - Google Gemini (with vision)
- Prompt templates — professional estimator prompts for text + photo
- Robust JSON extraction from AI responses
- Quick Estimate: text description → AI → BOQ items
- Photo Estimate: building photo → Claude Vision → BOQ items
- Create BOQ from estimate → saves as real positions
- API key masking in responses (only shows key_set: bool)

Frontend:
- AI Quick Estimate page with description input, location/currency selectors
- Loading animation during AI generation
- Results table with generated BOQ items
- "Save as BOQ" to persist in project
- AI Settings in Settings page — provider selection, API key input
- Sidebar: "AI Estimate" with sparkle icon (top position)

Endpoints: GET/PATCH /ai/settings, POST /ai/quick-estimate,
POST /ai/photo-estimate, POST /ai/estimate/{id}/create-boq,
GET /ai/estimate/{id}

User journey documented in docs/USER-JOURNEY.md

8 modules, 89+ API endpoints, 190+ files, 31,000+ lines
BOQ Templates (backend + frontend):
- 8 building types: Residential (35 pos), Office (17), Warehouse (13),
  School (15), Hospital (16), Hotel (11), Retail (11), Infrastructure (14)
- 132 total positions with realistic rates and qty_factors
- GET /boqs/templates — list all templates
- POST /boqs/from-template — create BOQ from template with area input
- Frontend: beautiful gallery with icons, configuration panel, preview
- Quantities calculated: qty_factor × area_m²

Activity Log:
- ActivityLog model (oe_boq_activity_log) — who/when/what/changes
- Event bus subscriber creates log entries on all BOQ mutations
- GET /boqs/{id}/activity — paginated activity feed
- Frontend: collapsible panel in BOQ editor with icons, relative time
- 16 action types with color-coded icons

Print CSS:
- Professional A4 landscape output (Ctrl+P from BOQ editor)
- Hides sidebar, header, buttons; shows clean table
- Section headers with background, repeated table headers per page
- Totals with bold borders, clean typography
- All animations/shadows stripped for clean print
Smart Autocomplete in BOQ Editor:
- Type 2+ chars in description → dropdown with matching cost items
- Shows: description, unit, rate from cost database
- Click suggestion → auto-fills description, unit, unit_rate
- Debounced (300ms), max 8 suggestions
- GET /costs/autocomplete?q=...&limit=8

AI Chat Panel in BOQ Editor:
- Toggle "AI Assistant" panel (right sidebar, 320px)
- Chat with AI: "add MEP for 5-story building"
- AI generates BOQ items as mini-table
- "Add all to BOQ" or select individual items
- POST /boqs/{id}/ai-chat
- Requires AI API key configured

Onboarding Wizard (4 steps):
- Step 1: Welcome screen with animated logo
- Step 2: Region selection (8 cards with flags → auto-set currency/standard)
- Step 3: AI setup (optional — enter API key, test connection)
- Step 4: Create first project from template
- Full-screen, progress dots, smooth transitions
- Shows only on first login (localStorage flag)

Database Import:
- POST /costs/import/file — upload Excel/CSV pricing database
- Flexible column detection (EN/DE aliases)
- European number format support
- Auto-generates codes for missing ones
- Frontend: drag-and-drop page with preview and results
- "Import Database" button added to Cost Database page
Replaced bar chart icon with a modern calculator design:
- Calculator body with rounded corners
- Screen showing "1.2M" (cost estimate)
- 3x3 button grid with subtle styling
- Blue "=" button at bottom
- Animated button-by-button entrance
- Updated favicon to match
Frontend sent 'name' but backend expected 'boq_name' in
BOQFromTemplateRequest schema. Fixed the interface and mutation call.
Backend: POST /boqs/{id}/import/smart
- Accepts ANY file: Excel, CSV, PDF, photos (JPG/PNG), scans
- Auto-detects file type and chooses best extraction method:
  - Excel/CSV: direct structured parsing (no AI needed)
  - PDF: pdfplumber table/text extraction → AI parsing
  - Images: base64 → AI Vision (Claude/GPT-4/Gemini)
- AI prompt optimized for construction BOQ extraction:
  - Multi-language support (DE/EN/RU/FR/ES)
  - Preserves original descriptions
  - Auto-numbers ordinals, detects units from context
  - Extracts ALL items even without prices
- Returns: {imported, errors, total_items, method (direct/ai)}

Frontend:
- Import button in BOQ Editor toolbar
- Smart Import modal with drag-and-drop
- Accepts .xlsx, .csv, .pdf, .jpg, .jpeg, .png, .tiff
- Shows "AI-powered" badge when AI parsing used
- Preview results before confirming
- Toast notifications on success/error
- Also updated Project Dashboard import dialog
Backend:
- cad_import.py: DDC converter integration
  - find_converter() searches multiple paths for .exe
  - convert_cad_to_excel() async subprocess with 5min timeout
  - parse_cad_excel() extracts elements (category, type, volume, area)
  - summarize_cad_elements() creates text for AI processing
- Smart import now accepts .rvt, .ifc, .dwg, .dgn files
- 200MB file size limit for CAD (15MB for other types)
- CAD_IMPORT_PROMPT: specialized for BIM element → BOQ mapping
- If no converter found: returns download link to DDC GitHub releases

Frontend:
- Import dialogs accept CAD file types
- CAD-specific result display (element count, format)
- Missing converter → clickable GitHub download link
- Toast shows "CAD + AI provider" method info

Supported formats:
- Revit .rvt (2017-2025)
- IFC .ifc (2x3, 4x, 4.3)
- AutoCAD .dwg (2007-2024)
- MicroStation .dgn
Root cause: Activity log event handler writes to DB concurrently with
the main request, causing SQLite "database is locked" errors.

Fix: Enable WAL (Write-Ahead Logging) journal mode and set
busy_timeout=5000ms via SQLAlchemy engine connect event.

This allows concurrent reads during writes, eliminating lock errors
in development. Production PostgreSQL is unaffected.

Tested: all 12 core endpoints return 200 OK.
Added missing translation keys:
- assemblies.title → "Assemblies"
- schedule.title → "4D Schedule"
- nav.5d_cost_model → "5D Cost Model"
- nav.templates → "Templates"

Sidebar AI Estimate button:
- Purple gradient background (from-violet to-cyan)
- "AI" badge with gradient pill
- Visually distinct from other nav items
Complete rewrite of AI Estimate page with tabbed interface:

Input types (2 rows × 3 cards):
Row 1:
- Text Description — describe project, AI generates full BOQ
- Photo / Scan — upload building photo, AI Vision analyzes
- PDF Document — upload BOQ/specs, AI extracts positions

Row 2:
- Excel / CSV — upload spreadsheet, direct parse or AI
- CAD / BIM — upload .rvt/.ifc/.dwg/.dgn, DDC converter + AI
- Paste — copy-paste from Excel/Word, AI parses

Features:
- 2×3 card grid with icons, descriptions, click to select
- Selected card: blue border with subtle background
- File tabs: drag-and-drop upload area with format hints
- Image preview for photos
- File info display (name, size, type badge)
- Shared results table across all input types
- Save as BOQ dialog with project selector
- Loading shimmer animation during AI processing
- AI-powered / Direct parse badge on results
Replaced pill tab bar with beautiful 2×3 card grid:
- Each source type is a large clickable card with:
  - Colored gradient icon (blue, violet, red, green, amber, slate)
  - Bold label + description text
  - Hover lift animation (-translate-y-0.5)
  - Active state: blue border, subtle background, checkmark badge
  - Press animation (scale 0.98)
- Responsive: 2 columns mobile, 3 columns desktop
- Staggered entrance animation per card
Problem: When switching to non-English languages, new keys
(assemblies.title, schedule.title, nav.5d_cost_model, etc.)
showed as raw key names because backend locale files didn't
have them, and the bundled English fallback got overwritten
by backend's incomplete English response.

Fix: Skip loading English from backend API — always use the
bundled English fallback which contains ALL keys. Other
languages still load from backend and fall back to English
for any missing keys.
Redesigned 2×3 grid from vertical cards to horizontal:
- Icon on left (40×40px), text on right
- Compact height, professional look
- Active: blue icon bg with white icon, blue text
- Inactive: subtle bg, gray icon, hover darkens
- Less visual noise: single blue accent color
- Truncated descriptions for clean layout
Added prominent card on /costs/import page:
- "CWICR Cost Database — 55,000+ items" with DDC branding
- GitHub download button linking to releases page
- Badges: 55,719 items, 9 languages, Excel/CSV
- Blue gradient background with database icon
- "or upload your own file" divider below
- Instruction to download then upload
AI Estimate page (/ai-estimate):
- Not configured: prominent setup card with sparkle icon,
  "Connect your AI to get started" message, Configure button,
  provider list (Anthropic/OpenAI/Gemini)
- Configured: green status bar with pulsing dot, "AI Connected",
  model name, green indicators for Text/Photo/PDF/CAD
- Fixed isConfigured check to use actual API response
  (anthropic_api_key_set boolean, not status string)

Settings page:
- Fixed AISettings interface to match backend response
  (anthropic_api_key_set: boolean instead of anthropic_api_key: string)
- Fixed provider key display (shows masked "sk-••••" when set)
- Fixed all TypeScript errors from type mismatch
Import page: 3×3 grid of regional databases
Backend: POST /costs/load-cwicr/{db_id} — reads from DDC Toolkit
Priority: Parquet > Excel for reliability
Changes:
- Renamed ENG_TORONTO to "English (International)" with UK flag
- Added "Popular" badge to English and German databases
- Added regions: "DACH", "CIS", "LatAm", "Gulf", "South Asia"
- Progress panel during import:
  - Shimmer progress bar with elapsed time counter
  - Estimated duration message (1-3 min)
  - Log output (monospace, color-coded: green=success, red=error)
- Result summary after completion: imported/skipped counts, filename
- Timer shows seconds elapsed during import
- Cost import page: flagcdn.com PNG flags for all 9 databases
- Language switcher: flagcdn.com PNG flags for all 20 languages
- Added 'country' code to SUPPORTED_LANGUAGES for flag mapping
- Removed emoji flags — consistent real flag images everywhere
- Removed "Popular" badge from databases
- English database: US flag, "English (US / UK / Canada)"
- All language names in native script: Deutsch, Français, Español,
  Português, Русский, العربية, 中文, हिन्दी
- Reordered: English first, then by popularity
Major rewrite of load-cwicr endpoint:
- Deduplicates by rate_code (900K rows → 55K unique items)
- Combines rate_original_name + rate_final_name for rich descriptions
- Bulk insert with batch commits (500 items per batch)
- 13 seconds vs 41 minutes (180x faster)
- Returns: imported, skipped, unique_items, duration_seconds

New endpoints:
- DELETE /costs/clear-database?source=cwicr — delete imported items
- GET /costs/export/excel — download entire cost DB as Excel
Fixes:
- Export: use raw SQL query instead of CostSearchQuery (limit 500 cap)
- Delete: moved to /actions/clear-database to avoid /{item_id} conflict
- Export: moved to /actions/export-excel
- Bulk import: pass real dicts {} [] not strings "{}" "[]" for JSON fields

Tested:
- Import 55,719 items: 28.5s ✅
- Search "concrete": 200, 3 results ✅
- Autocomplete "con": 200, 3 results ✅
- Export Excel: 200, 2.3MB file ✅
- Delete cwicr: 200, 55,719 deleted ✅
Onboarding Wizard (4 steps):
1. Welcome — logo, title, get started
2. Cost Database — 9 CWICR databases with flags, one-click load,
   progress bar with elapsed time, checkmark on completion
3. AI Provider — Anthropic/OpenAI/Gemini selection, API key input,
   test connection, feature list
4. First Project — name, region/currency/standard (auto-synced)

Cost Import Page:
- "Loaded Databases" section showing total items + which DBs loaded
- Export Excel button (downloads cost_database.xlsx)
- Clear Database button with confirmation
- localStorage tracking of loaded databases
- CWICRDatabaseGrid persists loaded state

Costs Page:
- Total items count badge in header
- Export + Import buttons in header
Step 1 — Validation:
- Professional validation dashboard with score circle, summary,
  filterable results, suggestions, tooltips
- Score labels: Excellent/Good/Needs Review/Poor

Step 2 — Tendering (9th module):
- Backend: TenderPackage + TenderBid models, CRUD endpoints,
  bid comparison, status workflow (draft→issued→awarded)
- Frontend: package list, bid entry, comparison table
- Manifest: oe_tendering, depends on [oe_projects, oe_boq]

Step 3 — Reports:
- Reports center page with 2×3 card grid
- BOQ Report (PDF/Excel), Cost Report, GAEB XML,
  Validation Report, Schedule, 5D (coming soon)
- Download via authenticated fetch + blob URL
- Toast notifications on success/failure

Step 4 — GAEB XML Export:
- GET /boqs/{id}/export/gaeb — valid GAEB DA XML 3.3 (DP 83)
- Maps sections → BoQCtgy, positions → Items
- Unit conversion (pcs→Stk, lsum→psch)
- Returns .X83 filename

Sidebar updated: Reports nav item with FileBarChart icon
9 backend modules, 100+ API endpoints

Tested: Validate 200, PDF 200, Excel 200, CSV 200, GAEB 200
Root causes fixed:
1. Removed cross-module ForeignKey constraints (SQLite incompatible)
2. Changed relationship lazy="selectin" to lazy="raise" to avoid
   MissingGreenlet errors with SQLite async
3. Added try/catch for bids access in response builder
4. Made boq_id nullable in both model and response schema
5. Disabled wildcard event handler (causes greenlet conflicts)
6. Commented out event publishing in tendering service

Tested: POST /tendering/packages/ → 201 Created ✅
PDF Takeoff Viewer (/takeoff):
- Upload PDF construction drawings
- AI analysis to extract elements and quantities
- Results with category summaries (walls, doors, windows)
- Select items → add to BOQ
- Quick measurements manual entry
- Project + BOQ selector

CO2 Sustainability Calculator (/sustainability):
- GET /boqs/{id}/sustainability — calculates CO2 from BOQ materials
- 10 material CO2 factors (concrete 250kg/m3, steel 1800kg/t, etc.)
- SVG donut chart breakdown by material
- Rating system: A (<80), B (80-150), C (150-250), D (>250) kg CO2/m2
- Benchmark per m2

Branding polish:
- App name: "OpenEstimator.io" everywhere (was "OpenEstimate")
- Tagline: "Professional construction cost estimation platform"
- Backend config, i18n (all 20 languages), frontend fallback updated

Sidebar: added PDF Takeoff (FileSearch) + Sustainability (Leaf) nav items
KPI Dashboard:
- AnalyticsSection with SVG bar chart (value by project)
- StatusDonut SVG chart (BOQ status distribution)
- Aggregate stats: total projects, BOQs, value

API Audit (27 endpoints tested):
- Auth: Me 200 ✅
- Projects: List/Get 200 ✅
- BOQ: List/Get/Structured/Templates/Validate/CSV/Excel/PDF/GAEB/Activity 200 ✅
- BOQ: Sustainability 200 ✅ (12.5t CO2, Rating A)
- Costs: Search/Autocomplete 200 ✅
- Assemblies: List 200 ✅
- Schedule: List 200 ✅
- 5D: Dashboard/S-Curve/Budget 200 ✅
- AI: Settings 200 ✅
- Tendering: List 200 ✅
- System: Health/Modules/Rules/Locales 200 ✅

27/27 PASSED ✅
…lies

Backend:
- Authorization: ownership checks on all CRUD endpoints (projects, BOQ, schedule, tendering)
- CORS tightened: explicit methods/headers instead of wildcard
- Admin permission bypass logging
- Error response sanitization (no type exposure)
- Pagination standardized (max 100 across all modules)
- Cost DB import: ProcessPoolExecutor (no GIL blocking), micro-batch SQLite inserts
- Cost DB: UNIQUE(code,region) constraint, full components in import
- Vector indexing: ProcessPoolExecutor for ONNX embeddings
- DELETE cost item: MissingGreenlet fix (save code before expire_all)
- Assembly AI generation endpoint (search cost DB by description)
- Assembly paginated response with component_count
- In-memory cache for region stats/categories (30s TTL)
- DB indexes: region, is_active, source, unit, description

Frontend:
- CostsPage: search debounce 300ms, column sorting, pagination with page numbers,
  clear filters button, active filter count badge, delete confirmation,
  Custom badge, component type i18n, empty states for favourites/recent
- ImportDatabasePage: sync loaded state with API, i18n for all strings,
  fire-and-forget vector indexing
- AssembliesPage: search debounce, pagination, component count on cards,
  AI Generate dialog, template library (8 templates), loading spinner,
  i18n for CreateAssemblyPage
- AssemblyEditorPage: delete confirmation, project/BOQ dropdown picker,
  regional factors UI, total rate label clarification, save BOQ→Assembly
- CAD Takeoff: full converter cards with install/uninstall on /cad-takeoff
- Header: i18n time ago, notification Escape handler
- Accessibility: aria-modal, Escape handlers, aria-labels on search inputs
- Mobile: responsive grids, touch targets 44px minimum
- Shared types file (models.ts)
Schedule:
- Generate from BOQ uses real labor_hours from position resources
- Formula: (quantity × labor_hours) / (workers × hours_per_day)
- Regional work calendars: DACH 8h Mon-Fri, Gulf 10h Mon-Sat, Nordic 7.5h
- Fixed all MissingGreenlet bugs (ORM objects saved as dicts)
- Gantt: synchronized scroll, Today marker, SVG arrows fixed
- Gantt: progress slider debounce 500ms, theme colors for critical path
- Left panel reduced from 420px to 280px
- 2 demo BOQs: Residential House + Office Renovation with labor resources

Layout:
- Global project switcher dropdown in Header (works on all pages)
- Content max-width increased 1120px → 1440px
- Padding reduced for more working space
… cleanup

Schedule:
- Fixed MissingGreenlet in CPM calculation (snapshot ORM objects as dicts)
- Fixed MissingGreenlet in generate_from_boq (all ORM→dict)
- 11 regional work calendars (France 7h, Gulf 10h 6d, Brazil/China/India 6d)
- Work calendar badge in UI showing hours/days per region
- Overall project progress bar
- Activity filter (All/Critical/Delayed/In Progress)
- Export schedule as TSV
- Reset schedule button for regeneration
- CPM: 4 critical activities, 51 days duration
- PERT: P50=51d, P80=57d, P95=64d, buffer +6d

Layout:
- Cleaned 138 duplicate test projects
- Removed German-only demo BOQs
datadrivenconstruction and others added 28 commits April 5, 2026 09:51
…"Точка"→"Этап"

Punch List:
- Header: single row (title left, project+button right)
- Modal: two-column grid, inline priority radio buttons
- Kanban: priority stripe on left edge (red/orange/yellow/gray)
- Overdue: subtle red tint background

Requirements:
- Header: single compact row with icon
- Toolbar: all buttons in one non-wrapping row, icon-only on mobile
- RU: "Точка" → "Этап" for quality gate labels
…ents & AI

- Sidebar: two separate nav items with distinct icons (Ruler / FileSearch)
- /takeoff?tab=measurements — direct link to measurements view
- /takeoff?tab=documents — direct link to documents & AI view
- Active state correctly highlights only the matching tab
- Translations: nav.measurements + nav.documents_ai on all 21 languages
- 31 markups.* keys (add_markup, types, stamps, delete, export, etc.)
- 6 punch.* keys (no_project, no_results, title_required)
- 23 requirements.* keys (export, import CSV/JSON, regex hints, preview)
- All 21 languages: EN, DE, FR, ES, PT, RU, ZH, AR, HI, TR, IT, NL, PL, CS, JA, KO, SV, NO, DA, FI, BG
- Tips & Hints panel only shown on empty BOQ (not when working)
- Removed "How it works" hint from work page (unnecessary noise)
- Reduced header spacing (mb-6→mb-4, space-y-3→2, text-2xl→xl)
- Cleaner workspace for construction professionals
…orce, PDF export

Backend (oe_fieldreports):
- FieldReport model: weather, workforce, delays, safety, photos, signatures
- 10 endpoints: CRUD, submit/approve workflow, calendar view, PDF export
- Weather API integration (OpenWeatherMap, graceful fallback)
- Status: draft → submitted → approved

Frontend:
- Calendar view: monthly grid with colored dots by status
- List view: filterable table with weather icons
- Report form: weather, workforce by trade, work performed, delays
- Stats cards: total, by status, workforce hours, delay hours
- Route: /field-reports, sidebar: Tools > Field Reports

Tests: 472 passed, 0 failed
Backend (extends oe_documents):
- ProjectPhoto model: filename, caption, GPS lat/lon, tags, category, taken_at
- 8 endpoints: upload, list, gallery, timeline, file serve, update, delete
- MIME validation, path traversal protection, 50MB limit
- Storage: ~/.openestimator/photos/{project_id}/

Frontend:
- Gallery grid: responsive 2-4 columns with thumbnails
- Drag-drop upload with EXIF extraction (date, GPS)
- Lightbox: keyboard nav, caption, GPS, edit/delete
- Grid + Timeline view toggle
- Category filter: site/progress/defect/delivery/safety
- Route: /photos, sidebar: Tools > Project Photos

Tests: 472 passed, 0 failed. Build clean.
Punch List (CRITICAL):
- PunchItem interface: 6 fields renamed to match backend exactly
- assigned_to_id → assigned_to, photos_count → photos.length
- location string → location_x/location_y numbers
- Removed non-existent fields: assigned_to_name, document_name, created_by_name

Field Reports:
- Added projectId guards to fetchFieldReportSummary and fetchFieldReportCalendar

Photos:
- Added projectId guard to uploadPhoto

Tests: 472 passed, 0 failed
…endpoints

Backend:
- TakeoffMeasurement model: type, group, points, value, unit, depth, volume, BOQ link
- 9 endpoints: CRUD, bulk create (500 max), export CSV/JSON, summary, link-to-boq
- MeasurementRepository with project/document/page/group/type filters
- TakeoffService with export and aggregation
- Schemas with validation (Pydantic v2)

Tests: 472 passed, 0 failed
Polyline measurement:
- Multi-segment distance (click N points, double-click to finish)
- Cumulative distance label, segment midpoint labels
- Full undo support (per-point)

Volume measurement:
- Polygon + depth input dialog → V = area × depth (m³)
- Display: "V = X.XX m³ (A: Y.YY m² × D: Z.ZZ m)"
- Scale-aware recalculation

Measurement groups/layers:
- 8 predefined groups: General, Structural, Electrical, Plumbing, HVAC, Finishing, Excavation, Concrete
- Group color coding on canvas
- Visibility toggle per group (eye icon)
- Collapsible group headers with subtotals
- Group selector dropdown in sidebar

Excel export:
- CSV with Group/Type/Annotation/Value/Unit/Page columns
- Group subtotals per measurement type

TakeoffViewerModule: 1204 → 1647 lines
Tests: 472 passed, 0 failed. Build clean.
8 test sections:
- Field Reports: 10/10 (CRUD, submit, approve, calendar, summary, PDF)
- Photo Gallery: 8/8 (list, gallery, timeline, filters, category)
- Takeoff Measurements: 11/11 (CRUD, bulk, export, summary, link-to-boq)
- Requirements: 8/8 (CRUD, gates 1-4, export, import, stats)
- Markups: 8/8 (CRUD, stamps, scales, summary, export, link-to-boq)
- Punch List: 8/8 (CRUD, full workflow, summary)
- Cross-module Integration: 5/5 (measurement→BOQ, markup→BOQ, req→BOQ)
- Regression: 15/15 (all 20 modules, auth, security)

Fix: global PROJECT_ID declaration in main() for proper test context
…dpoint

Classification mapper:
- Revit/IFC → DIN 276 (26 categories), NRM (12), MasterFormat (12)
- Batch classification: map_elements_to_classification()
- Deterministic lookup, no AI needed

IFC QTO presets (5 total):
- Standard, Detailed, By Storey, By Material, Summary

New endpoint:
- POST /boqs/classify-elements — classify CAD elements against DIN 276/NRM/MasterFormat
- Returns mapped/unmapped counts

Tests: 472 passed, 0 failed
… dashboard

Pin-to-plan (Punch List):
- POST /items/{id}/pin-to-sheet — attach punch item to drawing location
- Links document_id, page, location_x/y in one call

Document links (Field Reports):
- POST /reports/{id}/link-documents — link reports to documents
- GET /reports/{id}/documents — get linked document metadata
- document_ids JSON field added to FieldReport model

Project dashboard (ALL modules in one call):
- GET /projects/{id}/dashboard — aggregated cross-module data
- BOQ stats, requirements coverage, punch items by status
- Field reports (total + this week), photos, measurements
- Schedule activities, risks, change orders

Tests: 512 passed, 0 failed
…version control

Sheet model (oe_documents_sheet):
- sheet_number, sheet_title, discipline, revision, scale, is_current
- version chain via previous_version_id

PDF splitting:
- POST /sheets/split-pdf — upload multi-page PDF → auto-split into sheets
- pdfplumber page extraction + thumbnail generation
- Regex-based sheet info detection (number, title, scale, revision)

Discipline auto-detection:
- A=Architectural, S=Structural, M=Mechanical, E=Electrical
- P=Plumbing, C=Civil, L=Landscape

Endpoints:
- GET /sheets (list with filters), GET /sheets/{id}, PATCH /sheets/{id}
- GET /sheets/disciplines, GET /sheets/{id}/versions (full chain)

Tests: 40 new unit tests (discipline detection, regex patterns, schemas)
Total: 512 passed, 0 failed
… pages

Buttons:
- All icons have shrink-0, buttons whitespace-nowrap
- Fixed variant="outline" → "secondary" in Field Reports
- Wrapped text in <span> for consistent inline layout

API guards:
- Added projectId guards to: markups fetchMarkups/fetchSummary,
  punchlist fetchSummary/fetchTeamMembers, requirements fetchStats

Empty states (3 variants per page):
- No project: "Select a project..."
- No data: "Create your first..." with action button
- No results: "No matching items, adjust filters"
- Applied to: Requirements, Field Reports, Markups, Photos, Punch List

Build: clean (0 errors)
…asurement + markup

5 new annotation tools alongside existing measurements:
- Cloud: revision cloud with scalloped arcs (click points, double-click to finish)
- Arrow: line with arrowhead (2 clicks)
- Text: click to place, inline text input overlay
- Rectangle: two-corner rectangle outline
- Highlight: semi-transparent filled rectangle

Color system:
- 6 preset annotation colors (Red, Blue, Green, Orange, Purple, Yellow)
- Auto-default per type (cloud=Red, arrow=Blue, text=Black)
- Color picker in sidebar when annotation tool active

Unified experience:
- Measurements AND annotations in one PDF viewer
- Both stored in same array, persisted to localStorage
- Separate sidebar sections (Measurements by group, Annotations)
- Undo/redo works for all operations
- Annotations skipped from BOQ export (measurement-only)

TakeoffViewerModule: 1647 → 2231 lines (+584)
Tests: 512 passed. Build clean.
…ence

Column confidence:
- Each column shows % of elements with non-null values (e.g. "volume 65%")
- Helps users understand data quality before grouping

Hierarchical tree view:
- Toggle Flat/Tree when group_by has 2+ columns
- Parent rows: first group column with aggregate sums
- Expand/collapse children with chevron icons
- Connector lines for visual hierarchy

Element detail panel:
- Click any group row → slide-over shows all elements in that group
- Full table with ALL columns, numeric totals at bottom
- Up to 500 elements per view with truncation warning

Backend: POST /cad-group/elements endpoint
Tests: 512 passed, 0 failed. Build clean.
Persistent sessions:
- CadExtractionSession model in DB (was 5-min in-memory)
- 24-hour TTL, dual storage (memory + DB fallback)
- Survives server restarts

Create BOQ from QTO:
- POST /cad-group/create-boq — one-click BOQ creation
- Project selector + BOQ name in UI
- Auto-navigate to BOQ editor after creation
- Graceful session expiry handling

Excel export:
- GET /cad-group/export — professional Excel with formatting
- Header row, data rows, bold grand total
- Auto-fitted column widths
- Browser download as .xlsx

Tests: 512 passed, 0 failed. Build clean.
- useProjectContextStore(s => s.activeProject) → s.activeProjectId (property didn't exist)
- EmptyState icon={ClipboardList} → icon={<ClipboardList size={48} />} (ReactNode, not component ref)
- Removed unused Project interface

This bug made the entire Field Reports page always show empty — projectId was always ''
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot @github
Copy link
Copy Markdown
Author

dependabot bot commented on behalf of github Apr 6, 2026

Labels

The following labels could not be found: ci, dependencies. Please create them before Dependabot can add them to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant