Checkpoint: Audit et refactoring : centralisation robuste du suivi lu/non lu, suppression des captures SQL silencieuses, migration d’unicité avec déduplication des lectures existantes, correction du reclassement AAP via classifyAap, nettoyage de cinq composants template non utilisés, nettoyage des lectures lors des purges/fusions RSS et découpage dynamique du frontend. 27 tests Vitest, TypeScript et build de production validés.
This commit is contained in:
10
drizzle/0012_fluffy_boomer.sql
Normal file
10
drizzle/0012_fluffy_boomer.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- Conserver la première lecture de chaque article avant d'imposer l'unicité.
|
||||
DELETE duplicate_read
|
||||
FROM `article_reads` AS duplicate_read
|
||||
INNER JOIN `article_reads` AS retained_read
|
||||
ON duplicate_read.`userId` = retained_read.`userId`
|
||||
AND duplicate_read.`articleType` = retained_read.`articleType`
|
||||
AND duplicate_read.`articleId` = retained_read.`articleId`
|
||||
AND duplicate_read.`id` > retained_read.`id`;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE `article_reads` ADD CONSTRAINT `article_reads_user_type_article_unique` UNIQUE(`userId`,`articleType`,`articleId`);
|
||||
1061
drizzle/meta/0012_snapshot.json
Normal file
1061
drizzle/meta/0012_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -85,6 +85,13 @@
|
||||
"when": 1783432258494,
|
||||
"tag": "0011_sharp_gambit",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "5",
|
||||
"when": 1786997741455,
|
||||
"tag": "0012_fluffy_boomer",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
mysqlTable,
|
||||
text,
|
||||
timestamp,
|
||||
uniqueIndex,
|
||||
varchar,
|
||||
json,
|
||||
} from "drizzle-orm/mysql-core";
|
||||
@@ -204,13 +205,20 @@ export type InsertRssSettings = typeof rssSettings.$inferInsert;
|
||||
|
||||
// ─── Suivi de lecture des articles ──────────────────────────────────────────
|
||||
|
||||
export const articleReads = mysqlTable("article_reads", {
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
userId: int("userId").notNull(),
|
||||
articleType: mysqlEnum("articleType", ["veille", "aap"]).notNull(),
|
||||
articleId: int("articleId").notNull(),
|
||||
readAt: timestamp("readAt").defaultNow().notNull(),
|
||||
});
|
||||
export const articleReads = mysqlTable(
|
||||
"article_reads",
|
||||
{
|
||||
id: int("id").autoincrement().primaryKey(),
|
||||
userId: int("userId").notNull(),
|
||||
articleType: mysqlEnum("articleType", ["veille", "aap"]).notNull(),
|
||||
articleId: int("articleId").notNull(),
|
||||
readAt: timestamp("readAt").defaultNow().notNull(),
|
||||
},
|
||||
(table) => [
|
||||
// Une lecture est une relation unique entre un utilisateur et un article.
|
||||
uniqueIndex("article_reads_user_type_article_unique").on(table.userId, table.articleType, table.articleId),
|
||||
],
|
||||
);
|
||||
|
||||
export type ArticleRead = typeof articleReads.$inferSelect;
|
||||
export type InsertArticleRead = typeof articleReads.$inferInsert;
|
||||
|
||||
Reference in New Issue
Block a user