b29a268b1d
- Move completed plan files to .plans/done/ - Move 18 open plan files to .plans/open/ - Update .gitignore to exclude .verified_plans temp file - Verified all 18 open plans still describe unimplemented issues
2.0 KiB
2.0 KiB
Implementation Plan: Issue #192 — Database Portability
Summary
Replace 5 MySQL-specific SQL expressions with platform-aware equivalents using a new PlatformHelper utility class, declare PostgreSQL and SQLite support in info.xml, add Docker infrastructure for all three backends, create integration tests, and set up CI pipeline.
Phase 1: Core Portability Fixes
- Create
lib/Db/PlatformHelper.phpwith 3 methods:getYearDiffExpression($db, $col)— age/duration calculationgetMonthExpression($db, $col)— extract monthgetYearExpression($db, $col)— extract year
- Update
lib/Service/QueryService.phplines 300, 318 — use PlatformHelper - Update
lib/Db/MemberMapper.phplines 165, 301 — use PlatformHelper - Update
lib/Db/LagerMapper.phpline 70 — use PlatformHelper - Update
appinfo/info.xml— add pgsql and sqlite database declarations
Phase 2: Docker Infrastructure
- Create
docker/postgres/docker-compose.yml - Create
docker/sqlite/docker-compose.yml - Add Makefile targets for postgres and sqlite
Phase 3: Integration Tests
- Create
tests/DatabasePortability/PlatformHelperTest.php
Phase 4: CI Pipeline
- Create
.gitea/workflows/database-portability.yml
Phase 5: Security Review
- Verify PlatformHelper introduces no SQL injection vectors
- Verify column expressions are hardcoded, not user-supplied
AC Verification Checklist
- appinfo/info.xml declares mysql, pgsql, and sqlite
- No MySQL-specific SQL remains (no TIMESTAMPDIFF, CURDATE, LIKE on date columns)
- PlatformHelper generates correct expressions for all 3 backends
- Age/duration filters use PlatformHelper
- Birthday-this-month filter uses PlatformHelper
- Lager findByYear uses PlatformHelper
- Docker Compose files exist for MySQL, PostgreSQL, and SQLite
- Integration test suite exists
- CI pipeline definition exists
- No SQL injection vectors introduced (all expressions use hardcoded column names)