refactor: remove test.db, use only posterg.db for all environments

- Simplified Database.php determineDatabasePath to always use posterg.db
- Removed test.db auto-detection based on php_sapi_name
- Removed test.db targets from justfile (migrate-test removed)
- Removed CreateTestDatabase.php fixture script
- Updated migrate.sh to only init posterg.db
- Updated setup-dev.sh to init posterg.db
- Updated run-tests.php (removed DB_ENV=test env var)
- Updated deploy-db to use posterg.db
- Removed test.db file

refactor: remove empty fixtures directory
This commit is contained in:
Théophile Gervreau-Mercier
2026-04-27 18:07:03 +02:00
parent 780105eec0
commit 7e26351f4b
12 changed files with 195 additions and 496 deletions

View File

@@ -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

12
TODO.md
View File

@@ -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

View File

@@ -36,7 +36,8 @@ a:hover {
text-decoration: none;
}
body > header {
header {
vertical-align: center;
flex-shrink: 0;
background: linear-gradient(
180deg,
@@ -45,17 +46,8 @@ body > header {
var(--gradient-3) 66%,
var(--gradient-4) 100%
);
}
body > header nav {
padding: var(--space-s) var(--space-s);
display: flex;
align-items: center;
justify-content: space-between;
font-size: var(--step-2);
}
.nav-logo {
.nav-logo {
font-family: var(--font-display);
letter-spacing: 0.12em;
text-transform: uppercase;
@@ -64,16 +56,16 @@ body > header nav {
text-shadow:
0 0 16px var(--header-shadow-strong),
0 0 32px var(--header-shadow-soft);
}
}
.nav-left {
.nav-left {
display: flex;
align-items: center;
gap: var(--space-l);
}
}
.nav-left-links,
.nav-right-links {
.nav-left-links,
.nav-right-links {
font-family: var(--font-display);
display: flex;
gap: var(--space-l);
@@ -81,51 +73,58 @@ body > header nav {
list-style: none;
margin: 0;
padding: 0;
}
}
body > header nav > a {
nav {
padding: var(--space-s) var(--space-s);
display: flex;
align-items: center;
justify-content: space-between;
font-size: var(--step-2);
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 {
ul {
display: flex;
gap: var(--space-l);
align-items: center;
list-style: none;
margin: 0;
padding: 0;
}
}
body > header nav ul a {
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 {
a,
ul a {
text-shadow:
0 0 16px var(--header-shadow-strong),
0 0 32px var(--header-shadow-soft);
}
}
body > header nav ul a:hover {
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 {
@@ -228,3 +227,7 @@ main {
animation-duration: 0.01ms !important;
}
}
fieldset {
background: unset;
}

View File

@@ -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';
}
/**

View File

@@ -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?

View File

@@ -0,0 +1 @@
[1777139640]

View File

@@ -1,253 +0,0 @@
<?php
/**
* Script to create a test database with sample data
* Run this script once to set up test.db for development
*/
$dbPath = __DIR__ . '/../test.db';
// Remove existing database if it exists
if (file_exists($dbPath)) {
unlink($dbPath);
echo "Removed existing test database\n";
}
try {
// Create database connection
$pdo = new PDO('sqlite:' . $dbPath);
$pdo->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);
}

View File

@@ -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

View File

@@ -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";

View File

@@ -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

View File

@@ -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"

View File

@@ -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