From 6e658b82152d1e5df188215bc2e149f1f6b7f165 Mon Sep 17 00:00:00 2001 From: Jonathan Bourdon Date: Tue, 5 May 2026 13:02:14 -0400 Subject: [PATCH] docs: add calendar integration spec --- docs/FEATURES/calendar-integrations.md | 249 ++++++++++++++++++ .../001-backend-calendar-source-foundation.md | 38 +++ ...002-curated-catalog-and-ics-import-sync.md | 37 +++ .../003-content-calendar-ui-integration.md | 36 +++ .../004-content-date-context-ui.md | 34 +++ .../005-user-ics-export-feed.md | 40 +++ 6 files changed, 434 insertions(+) create mode 100644 docs/FEATURES/calendar-integrations.md create mode 100644 docs/TASKS/calendar-integrations/001-backend-calendar-source-foundation.md create mode 100644 docs/TASKS/calendar-integrations/002-curated-catalog-and-ics-import-sync.md create mode 100644 docs/TASKS/calendar-integrations/003-content-calendar-ui-integration.md create mode 100644 docs/TASKS/calendar-integrations/004-content-date-context-ui.md create mode 100644 docs/TASKS/calendar-integrations/005-user-ics-export-feed.md diff --git a/docs/FEATURES/calendar-integrations.md b/docs/FEATURES/calendar-integrations.md new file mode 100644 index 0000000..135866a --- /dev/null +++ b/docs/FEATURES/calendar-integrations.md @@ -0,0 +1,249 @@ +# Calendar Integrations + +## Status + +Draft + +## Goal + +Add `.ics` calendar import and export support so teams can plan social content with public holidays, observances, marketing moments, and personal work dates visible in the Content calendar. + +The experience should feel familiar to users who already subscribe to calendars from Google Calendar, Android calendar apps, Apple Calendar, or Outlook. + +## User Outcomes + +- Organization admins can configure shared calendar sources that apply across the organization. +- Workspace admins can configure calendar sources for a specific workspace and see inherited organization sources. +- Users can configure private calendar sources for their own calendar view. +- Users can subscribe to a private Socialize `.ics` feed so their upcoming Socialize work appears in external calendar apps. +- Content planners can see dates such as Mother's Day, Christmas Eve, Ramadan, Queen's Day, public holidays, and marketing moments next to planned content. +- Users can search a curated catalog of trusted calendar sources instead of manually finding `.ics` URLs. + +## Calendar Source Scopes + +Calendar sources can exist at three scopes: + +- `Organization`: managed by organization admins and inherited by workspaces in that organization. +- `Workspace`: managed by workspace admins/managers for one workspace. +- `User`: private to one user. + +Organization calendars have an inheritance mode: + +- `Required`: inherited by all workspaces and cannot be hidden at the workspace level. +- `Optional`: inherited by default, but workspace admins can hide the source for that workspace. + +Workspace calendar settings must show inherited organization calendars as read-only sources. If an inherited source is optional, workspace settings may expose a workspace-level visibility override without allowing edits to the source itself. + +User calendar settings show contextual organization and workspace sources plus private user sources. Private user calendars are visible only to that user. + +## Permissions + +- Organization admins can add, edit, remove, refresh, and set inheritance behavior for organization calendar sources. +- Workspace admins/managers can add, edit, remove, and refresh workspace calendar sources. +- Any authenticated user can add, edit, remove, refresh, and manage their own private calendar sources and exported feed. +- Client approvers and external collaborators can view shared calendar context in workspaces they can access but cannot manage shared sources. +- Private user calendar sources never become visible to other users. + +## Curated Calendar Catalog + +Socialize maintains a searchable curated catalog of calendar source metadata. The catalog presents trusted external sources through a polished product experience. + +Catalog entries may point to providers such as: + +- Google exported `.ics` calendars +- government public holiday feeds +- trusted holiday or observance APIs that can be represented as `.ics` +- other verified public `.ics` sources + +Catalog metadata should include: + +- title +- description +- country +- region or subdivision +- language +- category, such as public holiday, cultural observance, religious observance, or marketing moment +- culture or religion when relevant +- provider name +- source URL or provider configuration +- trust level or verification status +- default color + +Initial curated catalog coverage should include: + +- country and region public holidays +- major cultural and religious observances +- common social and marketing moments, such as Mother's Day, Valentine's Day, Black Friday, Cyber Monday, Pride Month, and Earth Day + +Platform-specific social media event calendars are out of v1 unless they are added later as maintained catalog entries. + +Curated calendars are added and removed as whole calendar sources. V1 does not require editing individual imported events from curated sources. + +## Custom ICS Imports + +V1 supports custom calendar import by URL subscription only. + +One-time `.ics` file upload is deferred because URL subscriptions stay current and map better to the expected calendar-app mental model. + +Each imported source stores: + +- source scope +- source URL or catalog source reference +- display title +- color +- category +- enabled state +- last successful sync timestamp +- last attempted sync timestamp +- last sync error, when applicable + +## Import Sync + +Socialize fetches subscribed `.ics` calendars on a background schedule, for example every 6-12 hours. + +Calendar settings also provide a manual refresh action for sources the current user can manage. + +Imported events are normalized and stored for fast calendar rendering. Recurring events from the feed must be expanded into the date range needed by calendar views. The importer should support yearly observances and moving-date observances when the upstream feed provides them. + +The importer should preserve useful event fields where available: + +- title +- description +- start and end date/time +- all-day flag +- recurrence identity +- source event UID +- location +- source URL +- last modified timestamp + +Imported events are read-only in Socialize. + +## Timezones + +All-day imported events remain attached to their calendar date and should not shift backward or forward because of timezone conversion. + +Timed imported events follow these rules: + +- If the event has a timezone, Socialize respects that timezone and displays the event at the equivalent local time for the viewer. +- If the event has no timezone, Socialize treats it as a floating local time. +- Floating times use the workspace timezone for organization and workspace calendars. +- Floating times use the user's timezone for private user calendars. + +Exported user `.ics` feeds should use the user's timezone for display and include stable UTC timestamps for timed Socialize events where possible. + +## Content Calendar Experience + +Imported calendar events appear as read-only calendar context in the Content calendar. + +They should: + +- appear as all-day context entries when the source event is all-day +- use a distinct calendar-event style separate from Socialize content items +- be lower visual priority than actual content work on crowded days +- use the source calendar color +- be filterable by source, scope, and category +- never affect content status, approval state, deadlines, notifications, or workflow automation by themselves + +Each calendar source has a configurable color. + +- Curated catalog sources provide sensible default colors by category. +- Organization and workspace admins can change colors for shared calendars they manage. +- Users can change colors for private calendars. +- A later task may allow user-level display color overrides for inherited/shared sources. + +## Calendar Source Control + +The Content calendar includes a compact calendar source control. + +The control lists currently displayed calendar sources, grouped or labeled by: + +- Organization +- Workspace +- My calendars + +Each source has a visibility toggle. Inherited read-only sources still appear in this list. The last entry is `Add calendar`. + +The `Add calendar` flow lets users search the curated catalog or add a custom `.ics` URL, subject to their permissions and selected scope. + +V1 focuses on source-level visibility. Per-event hiding is deferred. + +## Content Creation From Events + +Imported events are not editable as Socialize objects. + +An imported event may provide a quick action such as `Create content for this date`. This opens the normal content creation flow with the planned date and event title prefilled. + +## Content Detail And Date Picker Context + +When a content item has a planned publish date, the content detail view should show compact calendar context pills near the publish date or scheduling area. + +Examples: + +- `Mother's Day` +- `Christmas Eve` +- `Ramadan` +- `Queen's Day` + +Each pill comes from a visible calendar source. Clicking a pill opens a small event detail popover or the matching calendar day. + +Calendar context pills are read-only hints. They do not automatically become content tags or hashtags. + +The content create/edit date picker should lightly mark dates that have visible calendar events and show event names in a small date context panel. + +Imported calendar events should not appear in unrelated dashboards or notification feeds in v1. + +## User ICS Export + +Each user can enable a private exported Socialize `.ics` subscription feed. + +The feed: + +- uses a private unguessable URL +- does not require login because calendar apps fetch it in the background +- can be regenerated or revoked by the user +- includes only that user's `my work` dates +- excludes imported holiday and observance events by default + +`My work` includes: + +- content items assigned to the user +- content items where the user is an approver +- content items the user created or owns, if ownership exists +- approval due dates +- planned publish dates +- campaign dates only when the user has access to that campaign + +Feed entries should avoid sensitive discussion details. They may include: + +- title +- date and time +- status +- workspace +- client +- campaign +- a link back to Socialize + +## Localization + +Imported event names are shown using the source-provided event name. + +Curated catalog metadata may be localized, including calendar titles and descriptions. + +## Out Of Scope For V1 + +- One-time `.ics` file upload +- Editing imported events in Socialize +- Per-event hide controls +- Automatic scheduling warnings or blocked dates +- Automatic hashtag creation from calendar events +- Imported event notifications +- Platform-specific event calendars unless maintained as curated sources +- Full holiday-rule engine maintained manually inside Socialize + +## Open Questions + +- Which initial countries, regions, cultures, religions, and marketing calendars should ship in the first curated catalog? +- Which backend library should be used for robust `.ics` parsing and recurrence expansion? +- What default sync cadence should be used in production? +- Should user-level color overrides for shared calendars be included in v1 or deferred? diff --git a/docs/TASKS/calendar-integrations/001-backend-calendar-source-foundation.md b/docs/TASKS/calendar-integrations/001-backend-calendar-source-foundation.md new file mode 100644 index 0000000..f3f0df5 --- /dev/null +++ b/docs/TASKS/calendar-integrations/001-backend-calendar-source-foundation.md @@ -0,0 +1,38 @@ +# Task: Backend calendar source foundation + +## Goal + +Add backend storage and APIs for organization, workspace, and user calendar sources. + +## Feature Spec + +- `docs/FEATURES/calendar-integrations.md` + +## Scope + +- Add a calendar integrations module under `backend/src/Socialize.Api/Modules/CalendarIntegrations`. +- Model calendar sources for organization, workspace, and user scopes. +- Support organization inheritance modes: required and optional. +- Track source URL, catalog reference, display title, color, category, enabled state, and sync metadata. +- Add endpoints to list visible sources for a workspace/user context. +- Add endpoints to create/update/delete sources according to scope permissions. +- Show inherited organization sources in workspace responses as read-only. +- Add validation for source URLs, colors, scope, and inheritance mode. +- Add focused backend tests for permissions and inherited source visibility. + +## Relevant Files + +- `backend/src/Socialize.Api/Modules/CalendarIntegrations/` +- `backend/src/Socialize.Api/Data/AppDbContext.cs` +- `backend/src/Socialize.Api/Program.cs` +- `backend/tests/Socialize.Tests/` +- `shared/openapi/openapi.json` +- `frontend/src/api/schema.d.ts` + +## Validation + +```bash +dotnet build backend/Socialize.slnx +dotnet test backend/Socialize.slnx +./scripts/update-openapi.sh +``` diff --git a/docs/TASKS/calendar-integrations/002-curated-catalog-and-ics-import-sync.md b/docs/TASKS/calendar-integrations/002-curated-catalog-and-ics-import-sync.md new file mode 100644 index 0000000..d8c1539 --- /dev/null +++ b/docs/TASKS/calendar-integrations/002-curated-catalog-and-ics-import-sync.md @@ -0,0 +1,37 @@ +# Task: Curated catalog and ICS import sync + +## Goal + +Add searchable curated calendar catalog metadata and background `.ics` import sync. + +## Feature Spec + +- `docs/FEATURES/calendar-integrations.md` + +## Scope + +- Add curated calendar catalog storage or seed data for trusted external calendar sources. +- Add catalog search/filter APIs by country, region, language, category, culture/religion, and provider. +- Add `.ics` fetch, parse, recurrence expansion, and normalized event storage. +- Support manual refresh for manageable sources. +- Track last attempted sync, last successful sync, and last sync error. +- Preserve all-day events without timezone date shifting. +- Respect timezone-bearing timed events and floating timed events according to the feature spec. +- Add backend tests for parsing, recurrence expansion, timezone behavior, and sync error handling. + +## Relevant Files + +- `backend/src/Socialize.Api/Modules/CalendarIntegrations/` +- `backend/src/Socialize.Api/Data/AppDbContext.cs` +- `backend/tests/Socialize.Tests/` +- `docs/FEATURES/calendar-integrations.md` +- `shared/openapi/openapi.json` +- `frontend/src/api/schema.d.ts` + +## Validation + +```bash +dotnet build backend/Socialize.slnx +dotnet test backend/Socialize.slnx +./scripts/update-openapi.sh +``` diff --git a/docs/TASKS/calendar-integrations/003-content-calendar-ui-integration.md b/docs/TASKS/calendar-integrations/003-content-calendar-ui-integration.md new file mode 100644 index 0000000..cab0f0f --- /dev/null +++ b/docs/TASKS/calendar-integrations/003-content-calendar-ui-integration.md @@ -0,0 +1,36 @@ +# Task: Content calendar UI integration + +## Goal + +Show imported calendar events and calendar source controls in the Content calendar. + +## Feature Spec + +- `docs/FEATURES/calendar-integrations.md` + +## Scope + +- Add calendar source data loading to the Content feature. +- Render imported events as read-only calendar context entries in Month, Week, and Upcoming views. +- Style imported events distinctly from Socialize content items and apply source colors. +- Add a calendar source control grouped by Organization, Workspace, and My calendars. +- Add visibility toggles for displayed sources. +- Add `Add calendar` as the last source-control entry. +- Add an add-calendar flow that supports curated catalog search and custom `.ics` URL subscriptions according to user permissions. +- Keep imported events lower visual priority than actual content work on crowded days. +- Add a quick action to create content from an imported event, prefilled with date and event title. + +## Relevant Files + +- `frontend/src/features/content/views/ContentItemsView.vue` +- `frontend/src/features/content/` +- `frontend/src/plugins/api.js` +- `frontend/src/locales/en.json` +- `frontend/src/locales/fr.json` + +## Validation + +```bash +cd frontend +npm run build +``` diff --git a/docs/TASKS/calendar-integrations/004-content-date-context-ui.md b/docs/TASKS/calendar-integrations/004-content-date-context-ui.md new file mode 100644 index 0000000..f491cab --- /dev/null +++ b/docs/TASKS/calendar-integrations/004-content-date-context-ui.md @@ -0,0 +1,34 @@ +# Task: Content date context UI + +## Goal + +Show calendar context while creating, editing, and viewing content items. + +## Feature Spec + +- `docs/FEATURES/calendar-integrations.md` + +## Scope + +- Show compact read-only calendar context pills near the publish date or scheduling area on content detail. +- Include same-day visible calendar events such as Mother's Day, Christmas Eve, Ramadan, and Queen's Day. +- Let users click a pill to open event details or navigate to the matching calendar day. +- Lightly mark dates with visible calendar events in the content create/edit date picker. +- Show event names in a small date context panel during date selection. +- Do not convert calendar context pills into hashtags or content tags automatically. +- Do not add scheduling warnings, blocking behavior, or notifications in this task. + +## Relevant Files + +- `frontend/src/features/content/views/ContentItemDetailView.vue` +- `frontend/src/features/content/views/ContentItemsView.vue` +- `frontend/src/features/content/` +- `frontend/src/locales/en.json` +- `frontend/src/locales/fr.json` + +## Validation + +```bash +cd frontend +npm run build +``` diff --git a/docs/TASKS/calendar-integrations/005-user-ics-export-feed.md b/docs/TASKS/calendar-integrations/005-user-ics-export-feed.md new file mode 100644 index 0000000..b3692f6 --- /dev/null +++ b/docs/TASKS/calendar-integrations/005-user-ics-export-feed.md @@ -0,0 +1,40 @@ +# Task: User ICS export feed + +## Goal + +Let each user subscribe to a private `.ics` feed containing their Socialize `my work` dates. + +## Feature Spec + +- `docs/FEATURES/calendar-integrations.md` + +## Scope + +- Add backend support for user export feed tokens. +- Generate private unguessable feed URLs that do not require login. +- Let users enable, revoke, and regenerate their export URL. +- Emit valid `.ics` containing only the user's `my work` dates. +- Include assigned content, approval work, owned/created content where available, approval due dates, planned publish dates, and accessible campaign dates. +- Exclude imported holiday and observance events by default. +- Avoid sensitive comments or approval discussion details in exported entries. +- Add a user settings UI for copying, revoking, and regenerating the feed URL. +- Add backend tests for feed authorization boundary, token regeneration, and event contents. + +## Relevant Files + +- `backend/src/Socialize.Api/Modules/CalendarIntegrations/` +- `backend/src/Socialize.Api/Modules/ContentItems/` +- `backend/src/Socialize.Api/Modules/Approvals/` +- `frontend/src/features/user-profile-settings/` +- `frontend/src/config.js` +- `backend/tests/Socialize.Tests/` + +## Validation + +```bash +dotnet build backend/Socialize.slnx +dotnet test backend/Socialize.slnx +cd frontend +npm run build +./scripts/update-openapi.sh +```