1+ /**
2+ * This migration moves `payload.timestamp` to top-level `timestamp`
3+ * for both `events:*` and `repetitions:*` collections.
4+ */
5+
6+ module . exports = {
7+ async up ( db ) {
8+ const collections = await db . listCollections ( { } , {
9+ authorizedCollections : true ,
10+ nameOnly : true ,
11+ } ) . toArray ( ) ;
12+
13+ // Separate collections by prefix
14+ const eventCollections = collections
15+ . filter ( col => / ^ e v e n t s : / . test ( col . name ) )
16+ . map ( col => col . name ) ;
17+
18+ const repetitionCollections = collections
19+ . filter ( col => / ^ r e p e t i t i o n s : / . test ( col . name ) )
20+ . map ( col => col . name ) ;
21+
22+ // Step 1: Process event collections
23+ for ( const collectionName of eventCollections ) {
24+ await db . collection ( collectionName ) . updateMany (
25+ { 'payload.timestamp' : { $exists : true } } ,
26+ [
27+ {
28+ $set : {
29+ timestamp : '$payload.timestamp' ,
30+ } ,
31+ } ,
32+ {
33+ $unset : 'payload.timestamp' ,
34+ } ,
35+ ]
36+ ) ;
37+ }
38+
39+ // Step 2: Process repetition collections
40+ for ( const collectionName of repetitionCollections ) {
41+ const collection = db . collection ( collectionName ) ;
42+ const cursor = collection . find ( { } ) ;
43+
44+ while ( await cursor . hasNext ( ) ) {
45+ const doc = await cursor . next ( ) ;
46+
47+ if ( doc . payload ?. timestamp ) {
48+ // Move timestamp from payload to root
49+ await collection . updateOne (
50+ { _id : doc . _id } ,
51+ {
52+ $set : { timestamp : doc . payload . timestamp } ,
53+ $unset : { 'payload.timestamp' : '' } ,
54+ }
55+ ) ;
56+ } else if ( doc . groupHash ) {
57+ // Attempt to find matching event
58+ let eventDoc = null ;
59+
60+ const projectId = collectionName . split ( ":" ) [ 1 ] ;
61+ const eventsCollectionName = `events:${ projectId } ` ;
62+
63+ eventDoc = await db . collection ( eventsCollectionName ) . findOne ( { groupHash : doc . groupHash } ) ;
64+
65+ if ( eventDoc ?. timestamp ) {
66+ await collection . updateOne (
67+ { _id : doc . _id } ,
68+ {
69+ $set : { timestamp : eventDoc . timestamp } ,
70+ }
71+ ) ;
72+ }
73+ }
74+ }
75+ }
76+ } ,
77+
78+ async down ( db ) {
79+ const collections = await db . listCollections ( { } , {
80+ authorizedCollections : true ,
81+ nameOnly : true ,
82+ } ) . toArray ( ) ;
83+
84+ const eventCollections = collections
85+ . filter ( col => / ^ e v e n t s : / . test ( col . name ) )
86+ . map ( col => col . name ) ;
87+
88+ const repetitionCollections = collections
89+ . filter ( col => / ^ r e p e t i t i o n s : / . test ( col . name ) )
90+ . map ( col => col . name ) ;
91+
92+ // Revert event collections
93+ for ( const collectionName of eventCollections ) {
94+ await db . collection ( collectionName ) . updateMany (
95+ { timestamp : { $exists : true } } ,
96+ [
97+ {
98+ $set : {
99+ 'payload.timestamp' : '$timestamp' ,
100+ } ,
101+ } ,
102+ {
103+ $unset : 'timestamp' ,
104+ } ,
105+ ]
106+ ) ;
107+ }
108+
109+ // Revert repetition collections
110+ for ( const collectionName of repetitionCollections ) {
111+ await db . collection ( collectionName ) . updateMany (
112+ { timestamp : { $exists : true } } ,
113+ [
114+ {
115+ $set : {
116+ 'payload.timestamp' : '$timestamp' ,
117+ } ,
118+ } ,
119+ {
120+ $unset : 'timestamp' ,
121+ } ,
122+ ]
123+ ) ;
124+ }
125+ } ,
126+ } ;
127+
0 commit comments