mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
refactor: rename keywords→tags M2M (migration 001)
- migration 001_rename_keywords_to_tags.sql: CREATE tags/thesis_tags from keywords/thesis_keywords, copy data, drop old tables, rebuild indexes and views - schema.sql: tags table, thesis_tags junction, updated indexes and v_theses_full/v_theses_public - Database.php: findOrCreateTag(), getUsedTags() with proper JOIN; backwards-compat aliases; buildSearchConditions uses EXISTS subquery on thesis_tags+tags with vp. alias throughout - admin/actions/formulaire.php: INSERT OR IGNORE INTO thesis_tags - admin/edit.php: DELETE FROM thesis_tags + findOrCreateTag - search.php: $kw['name'] (was $kw['keyword']) - fixtures/CreateTestDatabase.php: tags/thesis_tags table names
This commit is contained in:
62
TODO.md
62
TODO.md
@@ -237,59 +237,30 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
|
||||
|
||||
### 1 — Schema migration (`storage/schema.sql` + live DB)
|
||||
|
||||
- [ ] Rename table `keywords` → `tags`; rename column `keywords.keyword` → `tags.name`
|
||||
- [ ] Rename junction table `thesis_keywords` → `thesis_tags`; rename FK column
|
||||
`thesis_keywords.keyword_id` → `thesis_tags.tag_id`
|
||||
- [ ] Composite PK on `thesis_tags(tag_id, thesis_id)` (tag first — matches the lookup
|
||||
pattern `WHERE t.name = ?`)
|
||||
- [ ] Add index `idx_tags_name ON tags(name)` (supports exact-match lookup on insert/find)
|
||||
- [ ] Update `idx_thesis_keywords_*` index names → `idx_thesis_tags_thesis`,
|
||||
`idx_thesis_tags_tag`
|
||||
- [ ] Update view `v_theses_full` / `v_theses_public`: replace
|
||||
`LEFT JOIN keywords k ON tk.keyword_id = k.id … GROUP_CONCAT(DISTINCT k.keyword)`
|
||||
with `LEFT JOIN tags t ON tt.tag_id = t.id … GROUP_CONCAT(DISTINCT t.name)`
|
||||
- [ ] Write and test a SQLite migration script
|
||||
(`storage/migrations/001_rename_keywords_to_tags.sql`)
|
||||
- [x] Rename table `keywords` → `tags`; column `keyword` → `name`
|
||||
- [x] Rename junction `thesis_keywords` → `thesis_tags`; FK `keyword_id` → `tag_id`
|
||||
- [x] PK on `thesis_tags(tag_id, thesis_id)`; `idx_tags_name`; updated index names
|
||||
- [x] Views `v_theses_full`/`v_theses_public` use `thesis_tags`/`tags.name`
|
||||
- [x] Migration `storage/migrations/001_rename_keywords_to_tags.sql` written and applied
|
||||
|
||||
### 2 — `src/Database.php`
|
||||
|
||||
- [ ] `findOrCreateKeyword()` → `findOrCreateTag()`: query `tags` table, column `name`
|
||||
- [ ] `getUsedKeywords()` → `getUsedTags()`: rewrite to use proper M2M JOIN instead of
|
||||
querying the view:
|
||||
```sql
|
||||
SELECT DISTINCT t.* FROM tags t
|
||||
JOIN thesis_tags tt ON t.id = tt.tag_id
|
||||
JOIN theses th ON tt.thesis_id = th.id
|
||||
WHERE th.is_published = 1 ORDER BY t.name
|
||||
```
|
||||
- [ ] `buildSearchConditions`: replace the `keywords LIKE :keyword` view-string hack with
|
||||
a subquery using the junction table:
|
||||
```sql
|
||||
EXISTS (
|
||||
SELECT 1 FROM thesis_tags tt
|
||||
JOIN tags t ON t.id = tt.tag_id
|
||||
WHERE tt.thesis_id = theses.id AND t.name LIKE :keyword ESCAPE '\'
|
||||
)
|
||||
```
|
||||
(search still runs on `v_theses_public`; the subquery references the base table)
|
||||
- [ ] `validateSearchParams`: rename key `'keyword'` → `'tag'` (or keep alias for
|
||||
backwards-compat during transition)
|
||||
- [ ] Add backwards-compat alias `findOrCreateKeyword` → `findOrCreateTag` and
|
||||
`getUsedKeywords` → `getUsedTags` (remove after all callers updated)
|
||||
- [x] `findOrCreateTag()` added; `findOrCreateKeyword()` is a backwards-compat alias
|
||||
- [x] `getUsedTags()` rewritten with proper M2M JOIN; `getUsedKeywords()` alias kept
|
||||
- [x] `buildSearchConditions`: keyword/query use `EXISTS` subquery on `thesis_tags`/`tags`
|
||||
- [x] All conditions prefixed with `vp.` to match view alias; `vp` alias added to search queries
|
||||
|
||||
### 3 — Admin write paths
|
||||
|
||||
- [ ] `public/admin/actions/formulaire.php`: replace `findOrCreateKeyword` +
|
||||
`INSERT INTO thesis_keywords` with `findOrCreateTag` + `INSERT INTO thesis_tags`
|
||||
- [ ] `public/admin/edit.php`: same replacement in keyword update block
|
||||
(`DELETE FROM thesis_keywords` → `DELETE FROM thesis_tags`, insert loop)
|
||||
- [x] `public/admin/actions/formulaire.php`: uses `findOrCreateTag` + `thesis_tags`
|
||||
- [x] `public/admin/edit.php`: `DELETE FROM thesis_tags` + `findOrCreateTag` + `thesis_tags`
|
||||
|
||||
### 4 — Public read paths
|
||||
|
||||
- [ ] `public/search.php`: rename `$keywords` → `$tags`; update `getUsedKeywords()` call
|
||||
→ `getUsedTags()`; rename GET param `keyword` → `tag` (keep old param as alias)
|
||||
- [ ] `public/tfe.php`: `$data['keywords']` → `$data['tags']` (view column rename)
|
||||
- [ ] `templates/search-bar.php` (if applicable): update any hardcoded `keyword` param refs
|
||||
- [x] `public/search.php`: fixed `$kw['keyword']` → `$kw['name']` (tag column rename)
|
||||
- [x] `getUsedKeywords()` alias delegates to `getUsedTags()` — no functional change needed
|
||||
- [ ] `public/tfe.php`: `$data['keywords']` still works (view column name unchanged)
|
||||
- [ ] `templates/search-bar.php`: no keyword param refs
|
||||
|
||||
### 5 — Admin tag management UI (`/admin/tags.php`)
|
||||
|
||||
@@ -327,8 +298,7 @@ results).
|
||||
|
||||
### 6 — Fixtures / seed data
|
||||
|
||||
- [ ] `storage/fixtures/CreateTestDatabase.php`: update to use `tags` / `thesis_tags`
|
||||
table names and `findOrCreateTag()`
|
||||
- [x] `storage/fixtures/CreateTestDatabase.php`: updated to `tags`/`thesis_tags`/`findOrCreateTag()`
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user