Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/desktop/src/components/finder/views/calendar-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function CalendarView({ date, sessions, events, onNavigate }: CalendarVie
onNavigate({ date: today.toISOString() });
};

const weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const weekDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weekday labels are hard-coded in English and the week start is fixed to Monday, which ignores user locale. Use locale-aware formatting for day names and derive the first day of week from the active locale to ensure correct labels for non-English users and regions that start weeks on Sunday.

Prompt for AI agents
Address the following comment on apps/desktop/src/components/finder/views/calendar-view.tsx at line 40:

<comment>Weekday labels are hard-coded in English and the week start is fixed to Monday, which ignores user locale. Use locale-aware formatting for day names and derive the first day of week from the active locale to ensure correct labels for non-English users and regions that start weeks on Sunday.</comment>

<file context>
@@ -37,7 +37,7 @@ export function CalendarView({ date, sessions, events, onNavigate }: CalendarVie
     onNavigate({ date: today.toISOString() });
   };
 
-  const weekDays = [&quot;Sun&quot;, &quot;Mon&quot;, &quot;Tue&quot;, &quot;Wed&quot;, &quot;Thu&quot;, &quot;Fri&quot;, &quot;Sat&quot;];
+  const weekDays = [&quot;Mon&quot;, &quot;Tue&quot;, &quot;Wed&quot;, &quot;Thu&quot;, &quot;Fri&quot;, &quot;Sat&quot;, &quot;Sun&quot;];
 
   return (
</file context>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Week starts on Monday: verify grid/body alignment and consider locale-aware labels

Switching to Monday-first is fine, but please verify WorkspaceCalendar renders days in the same order to avoid header/body misalignment. Also consider deriving labels from locale instead of hard-coded English abbreviations.

Run this to locate potential Sunday-first assumptions and duplicated weekday arrays:

Optionally, replace the static array with a locale-aware, Monday-first calculation:

-  const weekDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
+  const weekDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; // TODO(why): Hard-coded for hotfix; consider locale-aware EEE with weekStartsOn=1.

If you want the full locale-aware refactor, I can provide a minimal diff using date-fns format/startOfWeek.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect WorkspaceCalendar implementation and any weekday-related logic
fd -t f 'workspace-calendar' | xargs -I{} sh -c 'echo "== {} =="; rg -n "week|weekday|startOfWeek|Sun|Mon|getDay" "{}" || true'

# Search for hard-coded weekday arrays across the repo
rg -n --glob '!node_modules' --glob '!*dist*' --glob '!*build*' --glob '!*target*' '"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"|weekDays'

Length of output: 763


Fix weekday-order mismatch — calendar header is Monday-first but shared util is Sunday-first

Found conflicting weekday arrays — this will risk header/body misalignment. Unify to a single source-of-truth and prefer locale-aware labels.

Files to check

  • apps/desktop/src/components/finder/views/calendar-view.tsx
    • Line ~40: const weekDays = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
    • Used at lines ~78 and ~83 to render header cells.
  • packages/utils/src/datetime.ts
    • Line ~105: const daysOfWeek = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]; (Sunday-first)

Actionable suggestions

  • Replace hard-coded arrays with a single exported util (e.g., getWeekDays({ weekStartsOn, locale })) in packages/utils and import it in calendar-view, or generate locale-aware short names via Intl.DateTimeFormat.
  • Ensure the calendar body (any code that maps dates to columns / uses getDay/getDay index) uses the same week start (weekStartsOn) so header and grid align.

Minimal inline replacement example (calendar-view.tsx)

- const weekDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
+ // locale-aware, Monday-first (example using Intl)
+ const weekDays = (() => {
+   const fmt = new Intl.DateTimeFormat(undefined, { weekday: "short" });
+   const monday = new Date(Date.UTC(2020, 0, 6)); // known Monday anchor
+   return Array.from({ length: 7 }).map((_, i) => fmt.format(new Date(monday.getTime() + i * 86400000)));
+ })();

If you want, I can provide a PR-ready refactor that either (a) exports a locale-aware getter from packages/utils/src/datetime.ts or (b) uses date-fns (format/startOfWeek) to standardize weekStartsOn across the codebase.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const weekDays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
// locale-aware, Monday-first (example using Intl)
const weekDays = (() => {
const fmt = new Intl.DateTimeFormat(undefined, { weekday: "short" });
const monday = new Date(Date.UTC(2020, 0, 6)); // known Monday anchor
return Array.from({ length: 7 }).map((_, i) => fmt.format(new Date(monday.getTime() + i * 86400000)));
})();
🤖 Prompt for AI Agents
In apps/desktop/src/components/finder/views/calendar-view.tsx around line 40,
the file defines a hard-coded Monday-first weekDays array that conflicts with
packages/utils/src/datetime.ts which is Sunday-first; replace the local array
with a single source-of-truth: import and call a shared utility (e.g.,
getWeekDays({ weekStartsOn, locale })) from packages/utils (or generate short
weekday names via Intl.DateTimeFormat with the same weekStartsOn), use that
returned array to render header cells, and update any calendar body logic that
maps dates to columns to apply the same weekStartsOn offset (normalize getDay()
indices using the weekStartsOn) so header and grid align.


return (
<div className="flex flex-col h-full">
Expand Down
7 changes: 7 additions & 0 deletions crates/calendar-apple/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ impl CalendarSource for Handle {
return None;
}

// experiment: check if the event is recurring
let is_recurring = unsafe {
let has_rules: Bool = msg_send![event, hasRecurrenceRules];
has_rules.as_bool()
};

Comment on lines +229 to +234
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Recurrence detection: confirm API availability and trim the comment (use “why”).

Calling hasRecurrenceRules via msg_send is reasonable, but please confirm it’s available across the minimum iOS/macOS targets you support. If any target lacks this selector, consider a fallback check using recurrenceRules != nil.

Also, the comment “experiment” doesn’t convey why we’re doing this. Replace with a short “why”.


🌐 Web query:

Is EKEvent.hasRecurrenceRules documented and available across supported iOS/macOS versions? Provide official Apple docs and minimum availability.

💡 Result:

EKEvent.hasRecurrenceRules is not an officially documented property by Apple for EventKit; it does not appear in Apple’s EventKit class reference or official documentation, and therefore its cross-platform or minimum version availability cannot be confirmed from authoritative Apple sources.

Official Apple Documentation

  • Apple’s official API documentation for EKEvent and its superclass EKCalendarItem document the recurrenceRules property, which is an array of EKRecurrenceRule objects, and methods to add or remove recurrence rules, but there is no mention of a hasRecurrenceRules property[4].
  • Official EventKit documentation recommends checking if an event is recurring by querying the recurrenceRules array—if it is non-empty, the event is recurring[4][5][7].

Availability and Platform Version

  • Because hasRecurrenceRules is not official, there is no stated minimum OS version for this property in either iOS or macOS.
  • The standard way across all supported versions (as far back as iOS 4 and macOS 10.8)[1][5] is to use recurrenceRules:
    if (event.recurrenceRules != nil && event.recurrenceRules.count > 0) { /* event is recurring */ }

Context in the Ecosystem

  • Mentions of hasRecurrenceRules are sometimes seen in third-party bindings, community tutorials, or language wrappers (such as Xamarin or .NET auto-generated docs)[10], but these are not authoritative, and typically reflect helpers or computed properties rather than Apple-defined API surface.

Summary Table

Property Apple-official? Min iOS version Min macOS version
EKEvent.hasRecurrenceRules No N/A N/A
EKEvent.recurrenceRules Yes iOS 4.0+ OS X 10.8+

References to recurrence rules in Apple documentation always use the recurrenceRules array and never a hasRecurrenceRules Boolean property.[4][7][5]

To check for recurring events, use event.recurrenceRules.count > 0, which is available and supported across all Apple platforms with EventKit support.

If you need confirmation from official Apple Developer documentation, see the recurrenceRules property of EKCalendarItem[4].

Citations:


Recurrence detection: use documented recurrenceRules and clarify the comment (why).

EKEvent.hasRecurrenceRules is not an Apple-documented API and its availability cannot be relied on. Use the documented recurrenceRules array (check for nil / count > 0) and replace the vague "experiment" comment with a short "why".

  • File: crates/calendar-apple/src/lib.rs — lines 229–234

Suggested replacement snippet:

// why: use the documented `recurrenceRules` to determine if an event is recurring
let is_recurring = unsafe {
    let rules: *mut objc::runtime::Object = msg_send![event, recurrenceRules];
    if rules.is_null() {
        false
    } else {
        let count: usize = msg_send![rules, count];
        count > 0
    }
};

Apply this change (or at minimum check recurrenceRules != nil) and remove the use of the non‑official hasRecurrenceRules selector.

🤖 Prompt for AI Agents
In crates/calendar-apple/src/lib.rs around lines 229 to 234, replace the unsafe
call to the non‑documented selector hasRecurrenceRules with a documented check
of recurrenceRules: send the recurrenceRules selector, test for null, and if
non‑null call count and treat the event as recurring when count > 0; also
replace the vague "experiment" comment with a brief "why: use the documented
`recurrenceRules` to determine if an event is recurring" and remove any use of
the non‑official selector.

let participants = unsafe { event.attendees().unwrap_or_default() };
let participant_list: Vec<Participant> = participants
.iter()
Expand All @@ -247,6 +253,7 @@ impl CalendarSource for Handle {
start_date: offset_date_time_from(start_date),
end_date: offset_date_time_from(end_date),
google_event_url: None,
is_recurring,
})
})
.sorted_by(|a, b| a.start_date.cmp(&b.start_date))
Expand Down
1 change: 1 addition & 0 deletions crates/calendar-google/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ impl CalendarSource for Handle {
start_date: start,
end_date: end,
google_event_url: Some(event.html_link.clone()),
is_recurring: false,
}
})
.collect();
Expand Down
2 changes: 2 additions & 0 deletions crates/calendar-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub struct Event {
pub start_date: DateTime<Utc>,
pub end_date: DateTime<Utc>,
pub google_event_url: Option<String>,
#[serde(default)]
pub is_recurring: bool,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a new non-optional field to a serde-deserializable struct will break deserialization of existing data that doesn’t include this field. Provide a default or make it optional to maintain backward compatibility.

Prompt for AI agents
Address the following comment on crates/calendar-interface/src/lib.rs at line 48:

<comment>Adding a new non-optional field to a serde-deserializable struct will break deserialization of existing data that doesn’t include this field. Provide a default or make it optional to maintain backward compatibility.</comment>

<file context>
@@ -45,6 +45,7 @@ pub struct Event {
     pub start_date: DateTime&lt;Utc&gt;,
     pub end_date: DateTime&lt;Utc&gt;,
     pub google_event_url: Option&lt;String&gt;,
+    pub is_recurring: bool,
 }
 
</file context>
Suggested change
pub is_recurring: bool,
#[serde(default)] pub is_recurring: bool,

}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand Down
4 changes: 4 additions & 0 deletions crates/db-user/src/events_migration_2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE
events
ADD
COLUMN is_recurring BOOLEAN DEFAULT FALSE;
Comment on lines +1 to +4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Make the new column NOT NULL with a safe default (backward-compatible and type-safe)

As written, existing rows may end up with NULLs depending on engine/version behavior. Given the Rust type is bool (non-Option), enforce NOT NULL and set a default. Recommended:

  • Simple, robust approach (preferred for correctness):
-ALTER TABLE
-  events
-ADD
-  COLUMN is_recurring BOOLEAN DEFAULT FALSE;
+ALTER TABLE
+  events
+ADD
+  COLUMN is_recurring BOOLEAN NOT NULL DEFAULT FALSE;
  • If you want to minimize table rewrite on some Postgres versions, use a 3-step approach:
    1. ADD COLUMN nullable,
    2. UPDATE existing rows to FALSE,
    3. ALTER COLUMN SET NOT NULL and SET DEFAULT FALSE.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ALTER TABLE
events
ADD
COLUMN is_recurring BOOLEAN DEFAULT FALSE;
ALTER TABLE
events
ADD
COLUMN is_recurring BOOLEAN NOT NULL DEFAULT FALSE;
🤖 Prompt for AI Agents
In crates/db-user/src/events_migration_2.sql around lines 1 to 4, the new
is_recurring column is added without NOT NULL which can produce NULLs
incompatible with the Rust bool type; modify the migration to make the column
NOT NULL with a safe default by either adding it as: ADD COLUMN is_recurring
BOOLEAN NOT NULL DEFAULT FALSE, or (to avoid table rewrite on some Postgres
versions) perform the 3-step safe approach: 1) ADD COLUMN is_recurring BOOLEAN
DEFAULT FALSE (nullable), 2) UPDATE events SET is_recurring = FALSE WHERE
is_recurring IS NULL, then 3) ALTER TABLE events ALTER COLUMN is_recurring SET
NOT NULL and ALTER COLUMN is_recurring SET DEFAULT FALSE.

1 change: 1 addition & 0 deletions crates/db-user/src/events_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ user_common_derives! {
pub end_date: DateTime<Utc>,
pub google_event_url: Option<String>,
pub participants: Option<String>,
pub is_recurring: bool,
}
Comment on lines +17 to 18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

New non-optional bool requires DB non-null guarantee

Adding a non-optional bool is good, but it must be backed by a NOT NULL column (with a default) to avoid deserialization failures when reading legacy rows.

  • Ensure the migration sets is_recurring NOT NULL DEFAULT FALSE and backfills existing records. See my comment on events_migration_2.sql for the exact change.
  • If there’s any chance of ingesting older serialized Events (e.g., cached JSON without this field), consider adding a serde default to avoid breakage:
-        pub is_recurring: bool,
+        #[serde(default)]
+        pub is_recurring: bool,

Note: Confirm user_common_derives! passes field attributes through as-is.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for occurrences of is_recurring ==="
rg --hidden -n "is_recurring" || true

echo
echo "=== Show file crates/db-user/src/events_types.rs (if exists) ==="
if [ -f "crates/db-user/src/events_types.rs" ]; then
  sed -n '1,240p' crates/db-user/src/events_types.rs || true
else
  echo "File not found: crates/db-user/src/events_types.rs"
fi

echo
echo "=== Search for migrations mentioning events or is_recurring ==="
rg --hidden -n "events_migration|events_migration_2.sql|events_migration_2|ALTER TABLE .*is_recurring|is_recurring.*NOT NULL|is_recurring.*DEFAULT" || true

echo
echo "=== Search for user_common_derives macro definition/usages ==="
rg --hidden -n "user_common_derives" || true

echo
echo "=== Try to show macro definition(s) for user_common_derives ==="
# Find files that contain the macro_rules or proc macro
rg --hidden -n "macro_rules! user_common_derives|proc_macro.*user_common_derives|fn user_common_derives" || true

# If found, print nearby context for each file
FILES=$(rg --hidden -n "user_common_derives" -l || true)
if [ -n "$FILES" ]; then
  for f in $FILES; do
    echo
    echo "---- $f ----"
    sed -n '1,240p' "$f" || true
  done
else
  echo "No files containing user_common_derives found."
fi

echo
echo "=== Search for serde(default) usages ==="
rg --hidden -n "#\\[serde\\(default\\)\\]|serde\\(default\\)" || true

Length of output: 31353


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== events_migration_2.sql ==="
if [ -f "crates/db-user/src/events_migration_2.sql" ]; then
  sed -n '1,240p' crates/db-user/src/events_migration_2.sql
else
  echo "NOT FOUND: crates/db-user/src/events_migration_2.sql"
fi

echo
echo "=== events_migration_1.sql ==="
if [ -f "crates/db-user/src/events_migration_1.sql" ]; then
  sed -n '1,240p' crates/db-user/src/events_migration_1.sql
else
  echo "NOT FOUND: crates/db-user/src/events_migration_1.sql"
fi

echo
echo "=== events_migration.sql ==="
if [ -f "crates/db-user/src/events_migration.sql" ]; then
  sed -n '1,240p' crates/db-user/src/events_migration.sql
else
  echo "NOT FOUND: crates/db-user/src/events_migration.sql"
fi

echo
echo "=== crates/db-user/src/events_ops.rs ==="
if [ -f "crates/db-user/src/events_ops.rs" ]; then
  sed -n '1,240p' crates/db-user/src/events_ops.rs
else
  echo "NOT FOUND: crates/db-user/src/events_ops.rs"
fi

echo
echo "=== crates/db-user/src/init.rs (relevant insert lines) ==="
if [ -f "crates/db-user/src/init.rs" ]; then
  sed -n '1,240p' crates/db-user/src/init.rs | nl -ba | sed -n '1,240p'
else
  echo "NOT FOUND: crates/db-user/src/init.rs"
fi

Length of output: 10034


Fix DB + serde + ops for new non-optional is_recurring field

Short: the repo already added the column with DEFAULT FALSE, but the migration, deserialization safety, and DB persistence need fixes so the non-optional bool can't cause runtime/serialization bugs.

Files to change

  • crates/db-user/src/events_migration_2.sql
    • Current: ADD COLUMN is_recurring BOOLEAN DEFAULT FALSE;
    • Change to ensure NOT NULL and backfill existing rows. Example:
      ALTER TABLE events ADD COLUMN is_recurring BOOLEAN NOT NULL DEFAULT FALSE;
      -- if needed (or as a separate migration):
      UPDATE events SET is_recurring = FALSE WHERE is_recurring IS NULL;
  • crates/db-user/src/events_types.rs
    • Add serde default to tolerate older serialized data:
      -        pub is_recurring: bool,
      +        #[serde(default)]
  •    pub is_recurring: bool,
    
    - (Confirmed) user_common_derives! preserves field-level attributes, so the above will be emitted as-is.
    
  • crates/db-user/src/events_ops.rs
    • Persist the field in INSERT/UPDATE (currently INSERT/UPDATE omit is_recurring, so callers' values are ignored). Example diffs:
      • INSERT: add column/value and param
      -    ..., google_event_url, participants
      +    ..., google_event_url, participants, is_recurring
      • VALUES: add :is_recurring
      • ON CONFLICT DO UPDATE SET: include is_recurring = :is_recurring
      • Update the named_params maps to include:
      +    ":is_recurring": event.is_recurring,
    • UPDATE query: add is_recurring = :is_recurring and the named param.

Notes

  • Migration currently includes DEFAULT FALSE (crates/db-user/src/events_migration_2.sql) but not NOT NULL — ensure migrations enforce NOT NULL (or add a follow-up migration that backfills and then enforces NOT NULL) to avoid any NULLs when deserializing into a non-optional bool.
  • Adding #[serde(default)] is recommended defensive programming for any legacy JSON/cached serialized Events.
  • Also verify tests/seeders that construct Event include the new field where necessary (many seeds already set is_recurring: false).
🤖 Prompt for AI Agents
In crates/db-user/src/events_types.rs around lines 17-18, the new non-optional
field is_recurring lacks a serde default attribute and will fail when
deserializing older data; add #[serde(default)] (or #[serde(default = "false")]
equivalent) to the is_recurring field so missing/NULL values deserialize to
false. Also update crates/db-user/src/events_migration_2.sql to add NOT NULL and
backfill existing rows (ALTER TABLE events ADD COLUMN is_recurring BOOLEAN NOT
NULL DEFAULT FALSE; or run UPDATE events SET is_recurring = FALSE WHERE
is_recurring IS NULL; then ALTER ... NOT NULL), and modify
crates/db-user/src/events_ops.rs to include is_recurring in INSERT and UPDATE
statements (add the column to INSERT, add :is_recurring to VALUES and ON
CONFLICT DO UPDATE SET, and include is_recurring = :is_recurring in UPDATE) and
add the named param to all named_params maps so callers’ values are persisted.

}

Expand Down
20 changes: 20 additions & 0 deletions crates/db-user/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub async fn onboarding(db: &UserDatabase, user_id: impl Into<String>) -> Result
end_date: chrono::Utc::now() + chrono::Duration::minutes(10),
google_event_url: None,
participants: None,
is_recurring: false,
};

let onboarding_session_id = db.onboarding_session_id();
Expand Down Expand Up @@ -240,6 +241,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::minutes(45),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 2: Tomorrow - with session (top 3 test)
Event {
Expand All @@ -253,6 +255,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(1) + chrono::Duration::hours(1),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 3: In 2 days - without session (top 3 test)
Event {
Expand All @@ -266,6 +269,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(2) + chrono::Duration::hours(2),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 4: In 3 days - with session (top 3 test)
Event {
Expand All @@ -279,6 +283,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(3) + chrono::Duration::hours(1),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 5: In 7 days - with session (should NOT be in top 3, tests append logic when active)
Event {
Expand All @@ -292,6 +297,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(7) + chrono::Duration::hours(2),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 6: In 14 days - without session (should NOT be in top 3)
Event {
Expand All @@ -305,6 +311,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(14) + chrono::Duration::hours(1),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 7: In 4 hours - Video Call with session
Event {
Expand All @@ -330,6 +337,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::hours(5),
google_event_url: Some("https://zoom.us/j/123456789?pwd=abc123".to_string()),
participants: None,
is_recurring: false,
},
// Event 8: In 6 hours - Quick sync without session
Event {
Expand All @@ -343,6 +351,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::hours(6) + chrono::Duration::minutes(15),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 9: Later today - Team retro with session
Event {
Expand All @@ -366,6 +375,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::hours(9),
google_event_url: Some("https://teams.microsoft.com/l/meetup-join/meeting123".to_string()),
participants: None,
is_recurring: false,
},
// Event 10: In 5 days - Client demo with session
Event {
Expand All @@ -391,6 +401,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(5) + chrono::Duration::hours(1) + chrono::Duration::minutes(30),
google_event_url: Some("https://meet.google.com/abc-defg-hij".to_string()),
participants: None,
is_recurring: false,
},
// Event 11: In 6 days - Workshop without session
Event {
Expand All @@ -404,6 +415,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(6) + chrono::Duration::hours(3),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 12: In 8 days - Interview with session
Event {
Expand All @@ -430,6 +442,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(8) + chrono::Duration::hours(1) + chrono::Duration::minutes(30),
google_event_url: Some("https://zoom.us/j/987654321?pwd=interview123".to_string()),
participants: None,
is_recurring: false,
},
// Event 13: In 10 days - Board meeting without session
Event {
Expand All @@ -443,6 +456,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(10) + chrono::Duration::hours(2),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 14: In 12 days - Training session with session
Event {
Expand All @@ -468,6 +482,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(12) + chrono::Duration::hours(2),
google_event_url: Some("https://company.webex.com/meet/security.training".to_string()),
participants: None,
is_recurring: false,
},
// Event 15: In 3 weeks - Conference without session
Event {
Expand All @@ -481,6 +496,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now + chrono::Duration::days(23),
google_event_url: None,
participants: None,
is_recurring: false,
},
// === PAST EVENTS (for NotesList section testing) ===
// Event 16: Yesterday - with session (should appear in notes)
Expand All @@ -495,6 +511,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now - chrono::Duration::days(1) + chrono::Duration::minutes(30),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 17: Last week - with session (should appear in notes)
Event {
Expand All @@ -508,6 +525,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now - chrono::Duration::days(7) + chrono::Duration::hours(1),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 18: 10 days ago - with session (should appear in notes)
Event {
Expand All @@ -521,6 +539,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now - chrono::Duration::days(10) + chrono::Duration::hours(2),
google_event_url: None,
participants: None,
is_recurring: false,
},
// Event 19: 2 weeks ago - without session (should not appear anywhere)
Event {
Expand All @@ -534,6 +553,7 @@ pub async fn seed(db: &UserDatabase, user_id: impl Into<String>) -> Result<(), c
end_date: now - chrono::Duration::days(14) + chrono::Duration::hours(1),
google_event_url: None,
participants: None,
is_recurring: false,
},
];

Expand Down
3 changes: 2 additions & 1 deletion crates/db-user/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl std::ops::Deref for UserDatabase {
}

// Append only. Do not reorder.
const MIGRATIONS: [&str; 21] = [
const MIGRATIONS: [&str; 22] = [
include_str!("./calendars_migration.sql"),
include_str!("./configs_migration.sql"),
include_str!("./events_migration.sql"),
Expand All @@ -151,6 +151,7 @@ const MIGRATIONS: [&str; 21] = [
include_str!("./chat_groups_migration_1.sql"),
include_str!("./events_migration_1.sql"),
include_str!("./session_participants_migration_1.sql"),
include_str!("./events_migration_2.sql"),
];

pub async fn migrate(db: &UserDatabase) -> Result<(), crate::Error> {
Expand Down
Loading
Loading