diff --git a/README.md b/README.md index 95c24db..2c16f1b 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Files are pushed to the server with rsync — there is no repo on the remote. ```bash just deploy # rsync app files → posterg:/var/www/posterg/ -just deploy-db # push local test.db → remote (only if remote DB is absent) +just deploy-db # push local posterg.db → remote (only if remote DB is absent) ``` `deploy-db` refuses to run if a database already exists on the server, to avoid diff --git a/TODO.md b/TODO.md index 4546d08..28b490c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,2 +1,10 @@ -- [x] Fix .gitignore path for storage/cache/ (was `app/storage/cache/`) -- [x] Untrack storage/cache/rate_limit/*.json files with jj +# TODO + +- [x] Update migrate.sh to only handle posterg.db +- [x] Update Database.php determineDatabasePath to always use posterg.db +- [x] Update justfile to remove test.db targets and references +- [x] Remove CreateTestDatabase.php fixture script +- [x] Update setup-dev.sh to only create posterg.db +- [x] Update run-tests.php to use posterg.db +- [x] Remove test.db file +- [x] Update deploy-db target in justfile diff --git a/app/public/assets/css/common.css b/app/public/assets/css/common.css index 885c82f..5788829 100644 --- a/app/public/assets/css/common.css +++ b/app/public/assets/css/common.css @@ -3,178 +3,177 @@ *, *::before, *::after { - box-sizing: border-box; + box-sizing: border-box; } html, body { - margin: 0; - padding: 0; - height: 100%; - overflow: hidden; + margin: 0; + padding: 0; + height: 100%; + overflow: hidden; } body { - font-family: var(--font-body); - background: var(--bg-primary); - color: var(--text-primary); - background: linear-gradient( - 180deg, - rgba(0, 0, 0, 0) 92%, - rgba(149, 87, 181, 1) 100% - ); - display: flex; - flex-direction: column; + font-family: var(--font-body); + background: var(--bg-primary); + color: var(--text-primary); + background: linear-gradient( + 180deg, + rgba(0, 0, 0, 0) 92%, + rgba(149, 87, 181, 1) 100% + ); + display: flex; + flex-direction: column; } a { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } a:hover { + text-decoration: none; +} + +header { + vertical-align: center; + flex-shrink: 0; + background: linear-gradient( + 180deg, + var(--gradient-1) 0%, + var(--gradient-2) 33%, + var(--gradient-3) 66%, + var(--gradient-4) 100% + ); + + .nav-logo { + font-family: var(--font-display); + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent-foreground); text-decoration: none; -} + text-shadow: + 0 0 16px var(--header-shadow-strong), + 0 0 32px var(--header-shadow-soft); + } -body > header { - flex-shrink: 0; - background: linear-gradient( - 180deg, - var(--gradient-1) 0%, - var(--gradient-2) 33%, - var(--gradient-3) 66%, - var(--gradient-4) 100% - ); -} + .nav-left { + display: flex; + align-items: center; + gap: var(--space-l); + } -body > header nav { + .nav-left-links, + .nav-right-links { + font-family: var(--font-display); + display: flex; + gap: var(--space-l); + align-items: center; + list-style: none; + margin: 0; + padding: 0; + } + + nav { padding: var(--space-s) var(--space-s); display: flex; align-items: center; justify-content: space-between; font-size: var(--step-2); -} -.nav-logo { - font-family: var(--font-display); - letter-spacing: 0.12em; - text-transform: uppercase; - color: var(--accent-foreground); - text-decoration: none; - text-shadow: + a { + font-family: var(--font-display); + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent-foreground); + text-decoration: none; + } + + ul { + display: flex; + gap: var(--space-l); + align-items: center; + list-style: none; + margin: 0; + padding: 0; + } + + ul a { + font-size: var(--step--1); + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent-foreground); + text-decoration: none; + transition: opacity 0.15s; + } + + a, + ul a { + text-shadow: 0 0 16px var(--header-shadow-strong), 0 0 32px var(--header-shadow-soft); -} + } -.nav-left { - display: flex; - align-items: center; - gap: var(--space-l); -} + ul a:hover { + opacity: 1; + } + } -.nav-left-links, -.nav-right-links { - font-family: var(--font-display); - display: flex; - gap: var(--space-l); - align-items: center; - list-style: none; - margin: 0; - padding: 0; -} - -body > header nav > a { - font-family: var(--font-display); - /*font-size: var(--step-0);*/ - letter-spacing: 0.12em; - text-transform: uppercase; - color: var(--accent-foreground); - text-decoration: none; -} - -body > header nav > ul { - display: flex; - gap: var(--space-l); - align-items: center; - list-style: none; - margin: 0; - padding: 0; -} - -body > header nav ul a { - font-size: var(--step--1); - letter-spacing: 0.12em; - text-transform: uppercase; - color: var(--accent-foreground); - text-decoration: none; - transition: opacity 0.15s; -} - -/* Subtle shadow on all header text to improve legibility against the gradient */ -body > header nav > a, -body > header nav ul a { - text-shadow: - 0 0 16px var(--header-shadow-strong), - 0 0 32px var(--header-shadow-soft); -} - -body > header nav ul a:hover { - opacity: 1; -} - -body > header nav ul a[aria-current="page"] { + ul a[aria-current="page"] { opacity: 1; border-bottom: 1px solid var(--header-nav-active-border); padding-bottom: 1px; + } } main { - flex: 1; - min-height: 0; + flex: 1; + min-height: 0; } /* ============================================================ SEARCH BAR (shared) ============================================================ */ .header-search-wrap { - padding: 0 0; - flex-shrink: 0; - background-color: var(--gradient-4); - background: linear-gradient(180deg, var(--gradient-4) 0%, #ffffffee 100%); + padding: 0 0; + flex-shrink: 0; + background-color: var(--gradient-4); + background: linear-gradient(180deg, var(--gradient-4) 0%, #ffffffee 100%); } .header-search-wrap form[role="search"] { - display: flex; - align-items: center; - gap: var(--space-2xs); - padding: var(--space-3xs) var(--space-s); - border: 1px solid var(--accent-primary); - border-radius: 10px; - background: var(--bg-primary); - width: 100%; - color: var(--accent-primary); + display: flex; + align-items: center; + gap: var(--space-2xs); + padding: var(--space-3xs) var(--space-s); + border: 1px solid var(--accent-primary); + border-radius: 10px; + background: var(--bg-primary); + width: 100%; + color: var(--accent-primary); } .header-search-wrap form[role="search"] svg { - color: var(--text-tertiary); - flex-shrink: 0; - width: 16px; - height: 16px; - stroke: var(--accent-primary); + color: var(--text-tertiary); + flex-shrink: 0; + width: 16px; + height: 16px; + stroke: var(--accent-primary); } .header-search-wrap form[role="search"] input { - flex: 1; - border: none; - font-size: var(--step--1); - color: var(--text-primary); - background: transparent; - padding: var(--space-3xs) 0; - font-family: inherit; + flex: 1; + border: none; + font-size: var(--step--1); + color: var(--text-primary); + background: transparent; + padding: var(--space-3xs) 0; + font-family: inherit; } .header-search-wrap form[role="search"] input::placeholder { - color: var(--accent-primary); + color: var(--accent-primary); } /* ============================================================ @@ -183,48 +182,52 @@ main { /* Visually-hidden but screen-reader-accessible */ .sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; } /* Skip-to-content link (visible only on keyboard focus) */ .skip-link { - position: absolute; - top: -999px; - left: 1rem; - z-index: 9999; - padding: var(--space-2xs) var(--space-s); - background: var(--accent-primary); - color: var(--text-primary); - font-size: var(--step--1); - font-weight: 600; - text-decoration: none; - border-radius: 0 0 4px 4px; + position: absolute; + top: -999px; + left: 1rem; + z-index: 9999; + padding: var(--space-2xs) var(--space-s); + background: var(--accent-primary); + color: var(--text-primary); + font-size: var(--step--1); + font-weight: 600; + text-decoration: none; + border-radius: 0 0 4px 4px; } .skip-link:focus { - top: 0; + top: 0; } /* Consistent keyboard-focus outline for all interactive elements */ :focus-visible { - outline: 2px solid var(--accent-primary); - outline-offset: 2px; + outline: 2px solid var(--accent-primary); + outline-offset: 2px; } /* Respect user motion preferences */ @media (prefers-reduced-motion: reduce) { - *, - *::before, - *::after { - transition-duration: 0.01ms !important; - animation-duration: 0.01ms !important; - } + *, + *::before, + *::after { + transition-duration: 0.01ms !important; + animation-duration: 0.01ms !important; + } +} + +fieldset { + background: unset; } diff --git a/app/src/Database.php b/app/src/Database.php index 686edfa..ad6621f 100644 --- a/app/src/Database.php +++ b/app/src/Database.php @@ -35,7 +35,7 @@ class Database { /** * Determine database path. - * Priority: explicit override → DB_ENV env-var → sapi auto-detect. + * Priority: explicit override → APP_ROOT /storage/posterg.db. * APP_ROOT is defined by bootstrap.php before any controller loads Database. */ private function determineDatabasePath($customPath = null): string { @@ -44,15 +44,7 @@ class Database { } $root = defined('APP_ROOT') ? APP_ROOT : __DIR__ . '/..'; - $testDb = $root . '/storage/test.db'; - $prodDb = $root . '/storage/posterg.db'; - - $env = getenv('DB_ENV'); - if ($env === 'test') return $testDb; - if ($env === 'prod') return $prodDb; - - // php -S (dev server) → test DB; everything else (nginx/fpm) → prod DB - return php_sapi_name() === 'cli-server' ? $testDb : $prodDb; + return $root . '/storage/posterg.db'; } /** diff --git a/app/storage/README.md b/app/storage/README.md index deb62e1..c4d6da0 100644 --- a/app/storage/README.md +++ b/app/storage/README.md @@ -188,25 +188,9 @@ Query `v_theses_public` view with filters: ## 🛠️ Development Workflow ### Local Development -1. Use `test.db` for development -2. Create via `just init-test-db` -3. Populate with `just create-fixtures` -4. Test queries before deployment - -### Schema Changes -1. Update `schema.sql` -2. Update `DATABASE_SPECIFICATION.md` -3. Test on `test.db` -4. Deploy to production (manual migration) - -### Testing -```bash -# Run tests on local database -just test-public-all - -# Check database stats -just stats-public -``` +1. Use `posterg.db` for development +2. Create via `just init-db` +3. Test queries before deployment ## 📞 Need Help? diff --git a/app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json b/app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json new file mode 100644 index 0000000..bb34157 --- /dev/null +++ b/app/storage/cache/rate_limit/f528764d624db129b32c21fbca0cb8d6.json @@ -0,0 +1 @@ +[1777139640] \ No newline at end of file diff --git a/app/storage/fixtures/CreateTestDatabase.php b/app/storage/fixtures/CreateTestDatabase.php deleted file mode 100644 index 4df10b5..0000000 --- a/app/storage/fixtures/CreateTestDatabase.php +++ /dev/null @@ -1,253 +0,0 @@ -setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - echo "Created new database: $dbPath\n"; - - // Read and execute schema - $schemaPath = __DIR__ . '/../schema.sql'; - if (!file_exists($schemaPath)) { - throw new Exception("Schema file not found: $schemaPath"); - } - - $schema = file_get_contents($schemaPath); - $pdo->exec($schema); - echo "Schema created successfully\n"; - - // Insert sample authors - $authors = [ - ['name' => 'Marie Dubois', 'email' => 'marie.dubois@example.com'], - ['name' => 'Jean Martin', 'email' => 'jean.martin@example.com'], - ['name' => 'Sophie Bernard', 'email' => 'sophie.bernard@example.com'], - ['name' => 'Lucas Petit', 'email' => 'lucas.petit@example.com'], - ['name' => 'Emma Leroy', 'email' => 'emma.leroy@example.com'], - ]; - - foreach ($authors as $author) { - $stmt = $pdo->prepare("INSERT INTO authors (name, email) VALUES (:name, :email)"); - $stmt->execute($author); - } - echo "Inserted " . count($authors) . " sample authors\n"; - - // Insert sample supervisors - $supervisors = [ - ['name' => 'Prof. Claire Fontaine'], - ['name' => 'Dr. Thomas Moreau'], - ['name' => 'Prof. Anne Laurent'], - ]; - - foreach ($supervisors as $supervisor) { - $stmt = $pdo->prepare("INSERT INTO supervisors (name) VALUES (:name)"); - $stmt->execute($supervisor); - } - echo "Inserted " . count($supervisors) . " sample supervisors\n"; - - // Insert sample tags (formerly keywords) - $sampleKeywords = [ - 'spéculation', 'narration', 'urbanisme', 'patrimoine', 'intime', - 'collectivité', 'film', 'cinéma', 'sociologie', 'anthropologie', - 'éphémérité', 'queer', 'écriture', 'poésie', 'écologie', - 'technologies', 'design', 'performance', 'installation', 'art numérique' - ]; - - foreach ($sampleKeywords as $keyword) { - $stmt = $pdo->prepare("INSERT INTO tags (name) VALUES (:name)"); - $stmt->execute(['name' => $keyword]); - } - echo "Inserted " . count($sampleKeywords) . " sample tags\n"; - - // Insert sample theses - $theses = [ - [ - 'identifier' => '2024-001', - 'title' => 'Espaces Urbains et Narration Collective', - 'subtitle' => 'Une exploration des récits de la ville', - 'year' => 2024, - 'is_doctoral' => 0, - 'orientation_id' => 1, // Arts Numériques - 'ap_program_id' => 1, // Narration Spéculative - 'finality_id' => 1, // Approfondi - 'synopsis' => 'Ce travail explore la manière dont les espaces urbains génèrent des récits collectifs. À travers une série d\'installations vidéo et sonores, je documente les histoires cachées des quartiers en transformation. Le projet interroge la mémoire collective et la façon dont l\'architecture influence nos récits personnels et communautaires.', - 'access_type_id' => 1, // Libre - 'is_published' => 1, - ], - [ - 'identifier' => '2024-002', - 'title' => 'Corps et Technologies', - 'subtitle' => 'Interfaces sensorielles', - 'year' => 2024, - 'is_doctoral' => 0, - 'orientation_id' => 4, // Installation-Performance - 'ap_program_id' => 2, // Design et Politique du Multiple - 'finality_id' => 1, // Approfondi - 'synopsis' => 'Cette recherche artistique examine la relation entre le corps humain et les technologies numériques. À travers des performances interactives, j\'explore comment les interfaces technologiques transforment notre perception corporelle et créent de nouvelles formes de présence. Le projet questionne l\'hybridation entre organique et numérique.', - 'access_type_id' => 1, // Libre - 'is_published' => 1, - ], - [ - 'identifier' => '2024-003', - 'title' => 'Poétiques du Quotidien', - 'subtitle' => NULL, - 'year' => 2024, - 'is_doctoral' => 0, - 'orientation_id' => 6, // Photographie - 'ap_program_id' => 3, // Atelier Pratiques Situées - 'finality_id' => 2, // Enseignement - 'synopsis' => 'Ce projet photographique documente les gestes ordinaires et les moments éphémères du quotidien. En utilisant une approche documentaire mêlée de fiction, je cherche à révéler la poésie cachée dans les rituels banals. Le travail questionne notre rapport au temps et à l\'attention dans un monde accéléré.', - 'access_type_id' => 1, // Libre - 'is_published' => 1, - ], - [ - 'identifier' => '2023-015', - 'title' => 'Écologies Affectives', - 'subtitle' => 'Cartographies sensibles des liens', - 'year' => 2023, - 'is_doctoral' => 0, - 'orientation_id' => 9, // Graphisme - 'ap_program_id' => 4, // LIENS - 'finality_id' => 1, // Approfondi - 'synopsis' => 'Ce travail de design graphique développe une méthodologie visuelle pour cartographier les relations affectives et les réseaux de soin. À travers des visualisations de données sensibles et des éditions expérimentales, le projet explore comment représenter l\'invisible des liens humains et des solidarités.', - 'access_type_id' => 1, // Libre - 'is_published' => 1, - ], - [ - 'identifier' => '2023-020', - 'title' => 'Mémoires Spéculatives', - 'subtitle' => 'Archives du futur', - 'year' => 2023, - 'is_doctoral' => 0, - 'orientation_id' => 10, // Typographie - 'ap_program_id' => 1, // Narration Spéculative - 'finality_id' => 3, // Spécialisé - 'synopsis' => 'Un projet éditorial qui imagine des archives futures à partir de traces présentes. En utilisant la typographie comme outil de spéculation temporelle, je crée des documents fictionnels qui interrogent notre rapport à l\'histoire et à la transmission. Le travail questionne la matérialité de la mémoire.', - 'access_type_id' => 2, // Interne - 'is_published' => 1, - ], - [ - 'identifier' => '2025-002', - 'title' => 'Performance et Politique du Geste', - 'subtitle' => NULL, - 'year' => 2025, - 'is_doctoral' => 0, - 'orientation_id' => 4, // Installation-Performance - 'ap_program_id' => 3, // Atelier Pratiques Situées - 'finality_id' => 1, // Approfondi - 'synopsis' => 'Cette recherche performative explore la dimension politique des gestes quotidiens. À travers une série de performances filmées, j\'examine comment les micro-actions peuvent constituer des formes de résistance. Le projet s\'intéresse aux corps en mouvement et à leur capacité à transformer l\'espace public.', - 'access_type_id' => 1, // Libre - 'is_published' => 1, - ], - ]; - - foreach ($theses as $thesis) { - $columns = implode(', ', array_keys($thesis)); - $placeholders = ':' . implode(', :', array_keys($thesis)); - $stmt = $pdo->prepare("INSERT INTO theses ($columns) VALUES ($placeholders)"); - $stmt->execute($thesis); - } - echo "Inserted " . count($theses) . " sample theses\n"; - - // Link authors to theses - $thesisAuthors = [ - ['thesis_id' => 1, 'author_id' => 1, 'author_order' => 1], - ['thesis_id' => 2, 'author_id' => 2, 'author_order' => 1], - ['thesis_id' => 3, 'author_id' => 3, 'author_order' => 1], - ['thesis_id' => 4, 'author_id' => 4, 'author_order' => 1], - ['thesis_id' => 5, 'author_id' => 5, 'author_order' => 1], - ['thesis_id' => 6, 'author_id' => 1, 'author_order' => 1], - ]; - - foreach ($thesisAuthors as $link) { - $stmt = $pdo->prepare("INSERT INTO thesis_authors (thesis_id, author_id, author_order) VALUES (:thesis_id, :author_id, :author_order)"); - $stmt->execute($link); - } - echo "Linked authors to theses\n"; - - // Link supervisors to theses - $thesisSupervisors = [ - ['thesis_id' => 1, 'supervisor_id' => 1, 'supervisor_order' => 1], - ['thesis_id' => 2, 'supervisor_id' => 2, 'supervisor_order' => 1], - ['thesis_id' => 3, 'supervisor_id' => 1, 'supervisor_order' => 1], - ['thesis_id' => 4, 'supervisor_id' => 3, 'supervisor_order' => 1], - ['thesis_id' => 5, 'supervisor_id' => 2, 'supervisor_order' => 1], - ['thesis_id' => 6, 'supervisor_id' => 3, 'supervisor_order' => 1], - ]; - - foreach ($thesisSupervisors as $link) { - $stmt = $pdo->prepare("INSERT INTO thesis_supervisors (thesis_id, supervisor_id, supervisor_order) VALUES (:thesis_id, :supervisor_id, :supervisor_order)"); - $stmt->execute($link); - } - echo "Linked supervisors to theses\n"; - - // Link tags to theses (thesis_tags junction) - $thesisKeywords = [ - ['thesis_id' => 1, 'tag_id' => 3], // urbanisme - ['thesis_id' => 1, 'tag_id' => 2], // narration - ['thesis_id' => 1, 'tag_id' => 6], // collectivité - ['thesis_id' => 2, 'tag_id' => 16], // technologies - ['thesis_id' => 2, 'tag_id' => 18], // performance - ['thesis_id' => 2, 'tag_id' => 20], // art numérique - ['thesis_id' => 3, 'tag_id' => 14], // poésie - ['thesis_id' => 3, 'tag_id' => 11], // éphémérité - ['thesis_id' => 3, 'tag_id' => 5], // intime - ['thesis_id' => 4, 'tag_id' => 15], // écologie - ['thesis_id' => 4, 'tag_id' => 17], // design - ['thesis_id' => 5, 'tag_id' => 1], // spéculation - ['thesis_id' => 5, 'tag_id' => 4], // patrimoine - ['thesis_id' => 6, 'tag_id' => 18], // performance - ['thesis_id' => 6, 'tag_id' => 9], // sociologie - ]; - - foreach ($thesisKeywords as $link) { - $stmt = $pdo->prepare("INSERT OR IGNORE INTO thesis_tags (tag_id, thesis_id) VALUES (:tag_id, :thesis_id)"); - $stmt->execute($link); - } - echo "Linked tags to theses\n"; - - // Link languages to theses (all in French) - for ($i = 1; $i <= 6; $i++) { - $stmt = $pdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (:thesis_id, 1)"); - $stmt->execute(['thesis_id' => $i]); - } - echo "Linked languages to theses\n"; - - // Link formats to theses - $thesisFormats = [ - ['thesis_id' => 1, 'format_id' => 3], // Vidéo - ['thesis_id' => 1, 'format_id' => 6], // Installation - ['thesis_id' => 2, 'format_id' => 4], // Performance - ['thesis_id' => 3, 'format_id' => 5], // Objet éditorial - ['thesis_id' => 4, 'format_id' => 1], // Site web - ['thesis_id' => 4, 'format_id' => 5], // Objet éditorial - ['thesis_id' => 5, 'format_id' => 5], // Objet éditorial - ['thesis_id' => 6, 'format_id' => 4], // Performance - ['thesis_id' => 6, 'format_id' => 3], // Vidéo - ]; - - foreach ($thesisFormats as $link) { - $stmt = $pdo->prepare("INSERT INTO thesis_formats (thesis_id, format_id) VALUES (:thesis_id, :format_id)"); - $stmt->execute($link); - } - echo "Linked formats to theses\n"; - - echo "\n✅ Test database created successfully!\n"; - echo "Database location: $dbPath\n"; - echo "\nYou can now test the search feature at: http://localhost/front-backend/repertoire.php\n"; - -} catch (Exception $e) { - echo "❌ Error: " . $e->getMessage() . "\n"; - exit(1); -} diff --git a/app/tests/README.md b/app/tests/README.md index 05ce1e6..826b02a 100644 --- a/app/tests/README.md +++ b/app/tests/README.md @@ -125,16 +125,13 @@ try { ## 🔧 Test Database -Tests use the test database at `database/test.db`. +Tests use the main database at `storage/posterg.db`. ### Setup Test Database ```bash # Create from schema just init-db - -# Create with fixtures (sample data) -just fixtures ``` ### Reset Test Database diff --git a/app/tests/run-tests.php b/app/tests/run-tests.php index f271469..9027710 100755 --- a/app/tests/run-tests.php +++ b/app/tests/run-tests.php @@ -5,10 +5,6 @@ * Runs all tests in the tests/ directory */ -// Tests always run against the test database; require an explicit opt-in so -// that a stray test.db on disk never silently redirects a production session. -putenv('DB_ENV=test'); - echo "╔════════════════════════════════════════════╗\n"; echo "║ Post-ERG Test Suite ║\n"; echo "╚════════════════════════════════════════════╝\n\n"; diff --git a/justfile b/justfile index ab68aeb..a9b6453 100644 --- a/justfile +++ b/justfile @@ -33,7 +33,6 @@ deploy: --chown="www-data:posterg" \ --exclude 'vendor' \ --exclude 'tests' \ - --exclude 'test.db' \ --exclude '*.md' \ --exclude '.git*' \ --exclude '.jj' \ @@ -80,9 +79,9 @@ deploy-nginx: [group('deploy')] deploy-db: - @ssh posterg '[ ! -f /var/www/posterg/storage/test.db ]' || (echo "ERROR: remote database already exists. Remove it manually if you intend to overwrite." && exit 1) - rsync -v --progress app/storage/test.db posterg:/var/www/posterg/storage/test.db - ssh posterg "chown www-data:posterg /var/www/posterg/storage/test.db && chmod 660 /var/www/posterg/storage/test.db" + @ssh posterg '[ ! -f /var/www/posterg/storage/posterg.db ]' || (echo "ERROR: remote database already exists. Remove it manually if you intend to overwrite." && exit 1) + rsync -v --progress app/storage/posterg.db posterg:/var/www/posterg/storage/posterg.db + ssh posterg "chown www-data:posterg /var/www/posterg/storage/posterg.db && chmod 660 /var/www/posterg/storage/posterg.db" # ============================================================================ # Testing @@ -90,20 +89,20 @@ deploy-db: [group('test')] test: - @DB_ENV=test php app/tests/run-tests.php + @php app/tests/run-tests.php [group('test')] test-unit: - @DB_ENV=test php app/tests/Unit/DatabaseTest.php - @DB_ENV=test php app/tests/Unit/RateLimitTest.php + @php app/tests/Unit/DatabaseTest.php + @php app/tests/Unit/RateLimitTest.php [group('test')] test-integration: - @DB_ENV=test php app/tests/Integration/SearchTest.php + @php app/tests/Integration/SearchTest.php [group('test')] test-security: - @DB_ENV=test php app/tests/Security/SecurityTest.php + @php app/tests/Security/SecurityTest.php [group('test')] syntax: @@ -117,41 +116,29 @@ syntax: [group('database')] migrate: @echo "Running migrations…" - @bash scripts/migrate.sh both - -[group('database')] -migrate-test: - @bash scripts/migrate.sh test - -[group('database')] -migrate-prod: - @bash scripts/migrate.sh prod + @bash scripts/migrate.sh [group('database')] init-db: - @sqlite3 app/storage/test.db < app/storage/schema.sql - @sqlite3 app/storage/test.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';" + @sqlite3 app/storage/posterg.db < app/storage/schema.sql + @sqlite3 app/storage/posterg.db "SELECT COUNT(*) || ' tables' FROM sqlite_master WHERE type='table';" [group('database')] reset-db: - @rm -f app/storage/test.db + @rm -f app/storage/posterg.db @just init-db [group('database')] query: - @sqlite3 app/storage/test.db + @sqlite3 app/storage/posterg.db [group('database')] show id: - @sqlite3 -column -header app/storage/test.db "SELECT * FROM v_theses_full WHERE id = {{id}};"; + @sqlite3 -column -header app/storage/posterg.db "SELECT * FROM v_theses_full WHERE id = {{id}};"; [group('database')] backup: - @sqlite3 app/storage/test.db .dump > app/storage/backup_$(date +%Y%m%d_%H%M%S).sql - -[group('database')] -fixtures: - @php app/storage/fixtures/CreateTestDatabase.php + @sqlite3 app/storage/posterg.db .dump > app/storage/backup_$(date +%Y%m%d_%H%M%S).sql # ============================================================================ # Utils diff --git a/scripts/migrate.sh b/scripts/migrate.sh index 6925362..379b10f 100755 --- a/scripts/migrate.sh +++ b/scripts/migrate.sh @@ -1,17 +1,14 @@ #!/usr/bin/env bash -# Initialise one or both SQLite databases from schema.sql. +# Initialise the Post-ERG SQLite database from schema.sql. # Safe to run on existing databases — schema uses IF NOT EXISTS / INSERT OR IGNORE. # Usage: -# scripts/migrate.sh # both test.db and posterg.db -# scripts/migrate.sh test # storage/test.db only -# scripts/migrate.sh prod # storage/posterg.db only +# scripts/migrate.sh # posterg.db (default) set -euo pipefail REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" APP_DIR="$REPO_ROOT/app" SCHEMA="$APP_DIR/storage/schema.sql" -TEST_DB="$APP_DIR/storage/test.db" PROD_DB="$APP_DIR/storage/posterg.db" init_db() { @@ -22,17 +19,4 @@ init_db() { echo " [$label] done" } -TARGET="${1:-both}" - -case "$TARGET" in - test) init_db "$TEST_DB" "test.db" ;; - prod) init_db "$PROD_DB" "posterg.db" ;; - both) - init_db "$TEST_DB" "test.db" - init_db "$PROD_DB" "posterg.db" - ;; - *) - echo "Usage: $0 [test|prod|both]" >&2 - exit 1 - ;; -esac +init_db "$PROD_DB" "posterg.db" diff --git a/scripts/setup-dev.sh b/scripts/setup-dev.sh index bff8d8a..040e1bd 100755 --- a/scripts/setup-dev.sh +++ b/scripts/setup-dev.sh @@ -34,12 +34,12 @@ else echo "✓ Cloned php-live-reload" fi -# Create test database if needed -if [ ! -f "storage/test.db" ]; then +# Create posterg.db if needed +if [ ! -f "storage/posterg.db" ]; then echo "" - echo "📊 Creating test database..." - sqlite3 storage/test.db < storage/schema.sql - echo "✓ Created test database" + echo "📊 Creating posterg.db…" + sqlite3 storage/posterg.db < storage/schema.sql + echo "✓ Created posterg.db" fi # Create data directories