Changes between Version 4 and Version 5 of P6


Ignore:
Timestamp:
04/25/26 21:47:03 (7 days ago)
Author:
211099
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P6

    v4 v5  
    224224)
    225225}}}
     226
     227=== 3.Detailed report on percentage change in collaborator count and invitation validation for a story
     228=== SQL
     229{{{
     230WITH
     231owned_story AS (
     232    SELECT s.story_id, s.short_description
     233    FROM story s
     234    JOIN writer w ON s.user_id = w.user_id
     235    WHERE s.story_id = 5
     236      AND s.user_id = :owner_user_id
     237),
     238invited_writer AS (
     239    SELECT u.user_id, u.username, u.user_name, u.surname
     240    FROM users u
     241    JOIN writer w ON u.user_id = w.user_id
     242    WHERE u.username = :invited_username
     243),
     244already_collaborating AS (
     245    SELECT 1
     246    FROM collaboration
     247    WHERE user_id  = (SELECT user_id  FROM invited_writer)
     248      AND story_id = (SELECT story_id FROM owned_story)
     249),
     250current_collaborators AS (
     251    SELECT
     252        u.username,
     253        u.user_name,
     254        u.surname,
     255        r.roles,
     256        p.permission_level,
     257        c.collab_created_at
     258    FROM collaboration    c
     259    JOIN users            u ON c.user_id  = u.user_id
     260    JOIN roles            r ON c.user_id  = r.user_id AND c.story_id = r.story_id
     261    JOIN permission_level p ON c.user_id  = p.user_id AND c.story_id = p.story_id
     262    WHERE c.story_id = (SELECT story_id FROM owned_story)
     263),
     264notification_preview AS (
     265    SELECT
     266        iw.user_id AS recipient_user_id,
     267        iw.username AS recipient_username,
     268        'You have been invited to collaborate on "'
     269            || os.short_description || '"' AS notification_content,
     270        'collaboration' AS type,
     271        '/story/' || os.story_id::VARCHAR   AS link
     272    FROM invited_writer iw
     273    CROSS JOIN owned_story os
     274)
     275SELECT
     276    cc.username,
     277    cc.user_name,
     278    cc.surname,
     279    cc.roles,
     280    cc.permission_level,
     281    cc.collab_created_at,
     282    COUNT(*) OVER () AS total_collaborators,
     283    np.notification_content AS pending_notification,
     284    CASE
     285        WHEN NOT EXISTS (SELECT 1 FROM owned_story)          THEN 'Failed: story not found or not owned by you'
     286        WHEN NOT EXISTS (SELECT 1 FROM invited_writer)       THEN 'Failed: invited user is not a writer'
     287        WHEN EXISTS     (SELECT 1 FROM already_collaborating) THEN 'User is already a collaborator'
     288        ELSE                                                       'Ready to add collaborator'
     289    END   AS status
     290FROM current_collaborators          cc
     291LEFT JOIN notification_preview      np ON np.recipient_username = :invited_username
     292ORDER BY cc.collab_created_at;
     293}}}
     294=== Relational Algebra
     295{{{
     296OwnedStory ←
     297π story_id, short_description
     298(
     299  σ s.story_id = :story_id ∧ s.user_id = :owner_user_id
     300  (
     301    story s
     302    ⨝ (s.user_id = w.user_id) writer w
     303  )
     304)
     305
     306InvitedWriter ←
     307π user_id, username, user_name, surname
     308(
     309  σ u.username = :invited_username
     310  (
     311    users u
     312    ⨝ (u.user_id = w.user_id) writer w
     313  )
     314)
     315
     316AlreadyCollaborating ←
     317σ user_id = (π user_id (InvitedWriter))
     318  ∧ story_id = (π story_id (OwnedStory))
     319(
     320  collaboration
     321)
     322
     323CurrentCollaborators ←
     324π
     325  u.username, u.user_name, u.surname,
     326  r.roles, p.permission_level,
     327  c.collab_created_at
     328(
     329  (
     330    (
     331      σ story_id = (π story_id (OwnedStory)) (collaboration c)
     332      ⨝ (c.user_id = u.user_id) users u
     333    )
     334    ⨝ (c.user_id = r.user_id ∧ c.story_id = r.story_id) roles r
     335  )
     336  ⨝ (c.user_id = p.user_id ∧ c.story_id = p.story_id) permission_level p
     337)
     338
     339NotificationPreview ←
     340π
     341  iw.user_id        → recipient_user_id,
     342  iw.username       → recipient_username,
     343  'You have been invited to collaborate on "' || os.short_description || '"'
     344                    → notification_content,
     345  'collaboration'   → type,
     346  '/story/' || os.story_id → link
     347(
     348  InvitedWriter iw
     349  ⨯ OwnedStory os
     350)
     351
     352Result ←
     353π
     354  cc.username,
     355  cc.user_name,
     356  cc.surname,
     357  cc.roles,
     358  cc.permission_level,
     359  cc.collab_created_at,
     360  COUNT(*) OVER ()  → total_collaborators,
     361  np.notification_content → pending_notification,
     362  CASE
     363    WHEN OwnedStory = ∅           → 'Failed: story not found or not owned by you'
     364    WHEN InvitedWriter = ∅        → 'Failed: invited user is not a writer'
     365    WHEN AlreadyCollaborating ≠ ∅ → 'User is already a collaborator'
     366    ELSE                          → 'Ready to add collaborator'
     367  END               → status
     368(
     369  CurrentCollaborators cc
     370  ⟕ (cc.username = np.recipient_username) NotificationPreview np
     371)
     372}}}