feat: المجموعة G — Redis خط أول والقاعدة خط احتياط
الأساس: common/cache — كاش-جانبي فوق Redis. مبدأ صارم: فشل Redis لا يُسقط الطلب (يُسجَّل ويُرجَع للقاعدة) — الكاش تحسين أداء لا مصدر حقيقة. - G1: لغة المستخدم في Redis (كانت استعلاماً قبل كل إشعار)؛ تُكتب عند PATCH /users/me فيصير الإصابة دائمة - G2/G3: توكنات FCM في Redis — يُبطَل عند register وعند اكتشاف توكن ميت. البث الجماعي صار بلا استعلامات قاعدة - G4: كاش tenant resolve/config + إبطال عند الإنشاء - G5: كاش التعرفة و ride-types + إبطال صريح عند أي إنشاء - G6: التقييم يتراكم في Redis، والقاعدة تُكتب مرة واحدة يومياً لكل طرف (حجز الكتابة ذرّي بـLua). التأخير مقصود ليبعد الاحتكاك بين الطرفين. أُضيف ratings.target_user_id و users.rating — تقييم السائق للراكب كان يُخزَّن بلا هدف فلا يُجمَّع أبداً - كاش الخرائط (route/reverse/geocode) بإحداثيات مقرَّبة 4 خانات (~11م): نداء انطلق كان يهيمن على p50 (2.9s). لا يُخزَّن الرجوع لخط مستقيم ولا استجابة فاشلة تصحيح: ادّعيت سابقاً أن tenants.resolve يعمل على كل request — خطأ. tenant_id يأتي من الـJWT؛ resolve يُستدعى عند الدخول و3 كنترولرات فقط. الحمل الأثقل فعلياً هو رفع موقع السائق (المجموعة H). هجرة: RatingsBothParties. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
857652404b
commit
a83dd7e5e5
@@ -0,0 +1,25 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* تقييم الطرفين (docs/17 — G6):
|
||||
* - `ratings.target_user_id` — الراكب المُقيَّم عندما يقيّمه السائق. بدونه كان
|
||||
* تقييم السائق للراكب يُخزَّن بلا هدف فلا يُجمَّع أبداً.
|
||||
* - `users.rating` — التقييم الظاهر للراكب، يُكتب مرة واحدة يومياً.
|
||||
*/
|
||||
export class RatingsBothParties1721820000000 implements MigrationInterface {
|
||||
public async up(q: QueryRunner): Promise<void> {
|
||||
await q.query(`ALTER TABLE tripz_ratings ADD COLUMN IF NOT EXISTS target_user_id uuid`);
|
||||
await q.query(
|
||||
`CREATE INDEX IF NOT EXISTS "IDX_tripz_ratings_tenant_target_user" ON tripz_ratings (tenant_id, target_user_id)`,
|
||||
);
|
||||
await q.query(
|
||||
`ALTER TABLE tripz_users ADD COLUMN IF NOT EXISTS rating numeric(3,2) NOT NULL DEFAULT 5`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(q: QueryRunner): Promise<void> {
|
||||
await q.query(`ALTER TABLE tripz_users DROP COLUMN IF EXISTS rating`);
|
||||
await q.query(`DROP INDEX IF EXISTS "IDX_tripz_ratings_tenant_target_user"`);
|
||||
await q.query(`ALTER TABLE tripz_ratings DROP COLUMN IF EXISTS target_user_id`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user