Skip to main content

SKOLE-ACTV — Activities Module

Module ID: SKOLE-ACTV | Version: 1.0 | Status: Active
Products: Parent App (view + engage) · Teacher App (create/manage) · Web App (view)

1. Overview

FieldValue
Module NameActivities
Module CodeACTV
Business ValueKeeps parents informed about school activities — sports days, field trips, cultural programs. Teachers post updates; parents can comment and react, creating a two-way communication channel.

Scope In

  • Teachers: Create, update, soft-delete activities; assign to specific student or school-wide
  • Parents: View activity feed, comment, react (like/love)
  • Pagination, type filtering, status filtering

Scope Out

  • Event RSVP / registration
  • Photo gallery per activity

2. Requirements

Functional Requirements (FR)

What the module must DO — actions, behaviors, and outcomes.
  • SKOLE-ACTV-FR001: The module shall allow teachers to create activities with title, description, type (event, announcement, achievement, homework), and status.
  • SKOLE-ACTV-FR002: The module shall enable teachers to assign activities to a specific student or make them school-wide.
  • SKOLE-ACTV-FR003: The module shall allow teachers to update and soft-delete activity records.
  • SKOLE-ACTV-FR004: The module shall provide parents with a paginated feed of school activities.
  • SKOLE-ACTV-FR005: The module shall allow filtering by activity type and status.
  • SKOLE-ACTV-FR006: The module shall perform server-side pagination for the activity feed using page and limit parameters.
  • SKOLE-ACTV-FR007: The module shall allow web admins to view all activity records for their school.

Non-Functional Requirements (NFR)

How well the module must do it — performance, security, and reliability.
  • SKOLE-ACTV-NFR001: The module shall behave predictably by defaulting pagination to page 1 and a limit of 10 items if not specified.
  • SKOLE-ACTV-NFR002: The module shall perform secure data filtering by excluding soft-deleted activities (deleted_status = 1) from all feeds.
  • SKOLE-ACTV-NFR003: The module shall maintain high availability for the parent feed as it is a primary engagement surface.

Constraints

Rules and boundaries — tech choices and platform restrictions.
  • C001: We must utilize the Engagement module for handling comments and reactions on activities because of the platform’s modular architecture.
  • C002: We must use a single activities table for all types to maintain a unified feed logic across apps.

3. Sub-modules / Backlog

IDSub-modulePriorityStatusEstimateLinked FR
SKOLE-ACTV-SM001Teacher activity managementP0Done3dFR001–FR004
SKOLE-ACTV-SM002Parent activity feedP0Done2dFR005–FR007
SKOLE-ACTV-SM003Web admin activity viewP1Done1dFR008

4. Logical Implementation

Activity Status State Machine

[draft] ──publish──→ [published]
[published] ──archive──→ [archived]
[published] ──delete──→ [deleted] (deleted_status=1)

Teacher Create Flow

POST /teachers-app/activities
  ├─ Input: { skole_id, title, description, activity_type, posted_by,
  │           posted_by_id, status, student_id? }
  └─ INSERT activities → return created

Parent View Flow

GET /parent-app/activity?skole_id=&activity_type=&status=&page=&limit=
  ├─ WHERE deleted_status = 0 AND skole_id = ?
  └─ ORDER BY created_at DESC, paginate

Error Handling

ScenarioHTTPMessage
Missing skole_id400”skole_id is required”
Activity not found (CRUD)404”Activity not found”

5. UI Requirements

Teacher App — ActivitiesScreen

IDScreenRouteDescription
SKOLE-ACTV-UI001ActivitiesScreen/activitiesFeed with create button, edit/delete per card
Components:
IDComponentProps
SKOLE-ACTV-UC001ActivityCardactivity, onEdit, onDelete, showActions
SKOLE-ACTV-UC002ActivityForminitialValues, onSubmit, loading
SKOLE-ACTV-UC003ActivityTypeChiptype
SKOLE-ACTV-UC004StatusBadge`status: draftpublishedarchived`

Parent App — Activities Feed

IDScreenRouteDescription
SKOLE-ACTV-UI002ActivitiesFeed/activitiesPaginated activity cards with reactions and comments
Additional Components:
IDComponentProps
SKOLE-ACTV-UC005ReactionBarreactions, onReact, entityId, entityType
SKOLE-ACTV-UC006CommentSectioncomments[], onSubmit, entityId, entityType
SKOLE-ACTV-UC007PaginationControlspage, totalPages, onPageChange

Web App

IDScreenRouteDescription
SKOLE-ACTV-UI003Activities Page/:skoleId/activitiesTabular activity list with CRUD for web admin

6. Conditional Expressions

IDExpressionTriggerTrue ActionFalse Action
SKOLE-ACTV-CE001deleted_status === 1DB queryExclude from resultsInclude
SKOLE-ACTV-CE002activity.student_id !== nullActivity card renderShow “Individual” badgeShow “School-wide” badge
SKOLE-ACTV-CE003user.type === 'staff'Activity screenShow edit/delete buttonsRead-only view
SKOLE-ACTV-CE004status === 'draft'Activity cardShow draft watermarkNormal display
SKOLE-ACTV-CE005page >= totalPagesPaginationDisable “Next” buttonEnable “Next”

7. Internal Module Connections

DirectionModuleData / EventCondition
ACTV → AUTHAuthJWT skole_id scopes feedEvery request
ACTV → STUDStudentsOptional student_id assigns activity to studentWhen student-specific
ENGG → ACTVEngagementComments/reactions via entity_type='activity'On comment or react

8. External Connections

IDServicePurposeFailure Behavior
SKOLE-ACTV-EX001PostgreSQL (Prisma)Read/write activities500 error

9. Database Tables

IDTableRole
SKOLE-ACTV-TB001activitiesAll school activities

activities Key Columns

ColumnTypeNotes
idInt PK
skole_idVarChar(15)Tenant key
titleVarChar(255)Activity title
descriptionTextFull description
activity_typeVarChar(50)event/announcement/achievement/homework
posted_byVarChar(50)Staff name
posted_by_idInt?FK → staff.id
student_idInt?Specific student target
statusVarChar(25)draft/published/archived
deleted_statusInt0=active, 1=deleted

10. API Endpoints Summary

IDMethodRouteAuthDescription
PARENT-01GET/parent-app/activityJWTActivity feed (paginated)
PARENT-02GET/parent-app/activity/:idJWTActivity detail
PARENT-03GET/parent-app/activity/categoriesJWTList categories
TEACH-01GET/teachers-app/activityJWTList activities
TEACH-02GET/teachers-app/activity/:idJWTActivity detail
TEACH-03POST/teachers-app/activityJWTCreate activity
TEACH-04PUT/teachers-app/activity/:idJWTUpdate activity
TEACH-05DELETE/teachers-app/activity/:idJWTDelete activity
ADMIN-01GET/web-app/activityJWTList all activities
ADMIN-02GET/web-app/activity/:idJWTActivity detail
ADMIN-03POST/web-app/activityJWTCreate activity
ADMIN-04PUT/web-app/activity/:idJWTUpdate activity

  • Auto-excludes deleted entries

PARENT-01: Activity Feed (Paginated)

Section 1: Endpoint Summary

Returns paginated feed of school activities (events, announcements, achievements) for parent’s school with filtering by type and status.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /parent-app/activity
  • Authentication: JWT Bearer Token (Parent)
  • Rate Limit: 100 requests per minute

Section 4: Query Parameters

ParameterTypeRequiredDefaultDescription
activity_typeStringNo-Filter: event, announcement, achievement, homework
statusStringNopublishedFilter: draft, published, archived
pageIntegerNo1Page number (1-indexed)
limitIntegerNo10Items per page (max: 50)

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "data": {
    "activities": [
      {
        "id": "UUID",
        "title": "Annual Sports Day 2026",
        "description": "Join us for a day of fun sports activities...",
        "activity_type": "event",
        "posted_by": "Mr. Rajesh Kumar",
        "status": "published",
        "created_at": "2026-03-15T10:00:00.000Z",
        "is_school_wide": true,
        "engagement_stats": {
          "likes": 45,
          "comments": 12
        }
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 10,
      "total": 87,
      "total_pages": 9
    }
  }
}

Section 7: Error Responses

401 - Unauthorized
{
  "status": "error",
  "code": "UNAUTHORIZED",
  "message": "Invalid JWT token"
}
400 - Invalid Pagination
{
  "status": "error",
  "code": "INVALID_PAGINATION",
  "message": "Page must be >= 1, limit <= 50"
}

Section 8: Implementation Examples

JavaScript:
const getActivityFeed = async (token, filters = {}) => {
  const params = new URLSearchParams({
    page: filters.page || 1,
    limit: filters.limit || 10,
    status: filters.status || 'published',
    ...filters
  });

  const response = await fetch(
    `https://api.skole.com/v1/parent-app/activity?${params}`,
    {
      method: 'GET',
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );

  const data = await response.json();
  return data.data;
};

// Usage
const feed = await getActivityFeed(token, { activity_type: 'event' });
console.log(`Loaded ${feed.activities.length} activities`);
Python:
def get_activity_feed(token: str, activity_type: str = None, page: int = 1) -> dict:
    url = 'https://api.skole.com/v1/parent-app/activity'
    headers = {'Authorization': f'Bearer {token}'}
    
    params = {
        'page': page,
        'limit': 10,
        'status': 'published'
    }
    
    if activity_type:
        params['activity_type'] = activity_type
    
    response = requests.get(url, headers=headers, params=params)
    return response.json()['data']

# Usage
feed = get_activity_feed(token, activity_type='event')

Section 9: Database Context

Tables:
  • activities (primary)
  • schools (join for isolation)
Query:
SELECT a.*, COUNT(*) OVER() as total
FROM activities a
WHERE a.skole_id = ? AND a.deleted_status = 0
  AND (? IS NULL OR a.activity_type = ?)
  AND a.status = ?
ORDER BY a.created_at DESC
LIMIT ? OFFSET ?
Indices: (skole_id, deleted_status, status), created_at DESC, activity_type

Section 10: Business Logic & Validations

Validation:
  • Page >= 1, limit <= 50
  • activity_type enum check
  • Status filter (published by default for parents)
  • Auto-excludes deleted entries
Business Logic:
  1. Scope to parent’s school (skole_id)
  2. Apply all filters
  3. Exclude deleted_status = 1 entries
  4. Count total matching
  5. Paginate and return with metadata
  • GET /parent-app/activity/:id - Single activity detail
  • GET /parent-app/activity/categories - List types

Section 12: Response Summary Table

StatusScenarioError CodeMessage
200 ✅Success-Activities retrieved
401 ❌UnauthorizedUNAUTHORIZEDInvalid JWT
400 ❌Bad paginationINVALID_PAGINATIONInvalid params

PARENT-02: Get Activity Detail

Section 1: Endpoint Summary

Fetch complete activity details including full description, engagement stats, and comments.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /parent-app/activity/:id
  • Authentication: JWT (Parent)

Section 3: Path Parameters

ParameterTypeRequiredDescription
idUUIDYesActivity ID

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "data": {
    "id": "UUID",
    "title": "Annual Sports Day 2026",
    "description": "Full description...",
    "activity_type": "event",
    "posted_by": "Mr. Rajesh Kumar",
    "status": "published",
    "is_school_wide": true,
    "created_at": "2026-03-15T10:00:00.000Z",
    "updated_at": "2026-03-15T10:00:00.000Z"
  }
}

Section 8: Implementation Examples

JavaScript:
const getActivityDetail = async (token, activityId) => {
  const response = await fetch(
    `https://api.skole.com/v1/parent-app/activity/${activityId}`,
    {
      method: 'GET',
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );

  return (await response.json()).data;
};

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-
404 ❌Not foundNOT_FOUND

PARENT-03: List Activity Categories

Section 1: Endpoint Summary

Returns list of available activity types/categories for filtering.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /parent-app/activity/categories
  • Authentication: JWT (Parent)

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "data": {
    "categories": [
      {
        "type": "event",
        "label": "Events",
        "count": 25
      },
      {
        "type": "announcement",
        "label": "Announcements",
        "count": 35
      },
      {
        "type": "achievement",
        "label": "Achievements",
        "count": 15
      },
      {
        "type": "homework",
        "label": "Homework",
        "count": 12
      }
    ]
  }
}

Section 8: Implementation Examples

JavaScript:
const getActivityCategories = async (token) => {
  const response = await fetch(
    'https://api.skole.com/v1/parent-app/activity/categories',
    {
      method: 'GET',
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );

  return (await response.json()).data.categories;
};

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

TEACH-01: List Activities

Section 1: Endpoint Summary

Teacher views all activities they’ve created with filtering and pagination.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /teachers-app/activity
  • Authentication: JWT (Staff)

Section 4: Query Parameters

ParameterTypeRequiredDescription
activity_typeStringNoFilter by type
statusStringNoFilter by status
pageIntegerNoPage number
limitIntegerNoItems per page

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "data": {
    "activities": [
      {
        "id": "UUID",
        "title": "...",
        "activity_type": "event",
        "status": "published",
        "created_at": "2026-03-15T10:00:00.000Z"
      }
    ],
    "pagination": {
      "total": 25,
      "page": 1,
      "limit": 10
    }
  }
}

Section 8: Implementation Examples

JavaScript:
const getMyActivities = async (token, filters = {}) => {
  const params = new URLSearchParams(filters);
  const response = await fetch(
    `https://api.skole.com/v1/teachers-app/activity?${params}`,
    {
      method: 'GET',
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );

  return (await response.json()).data;
};

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

TEACH-02: Get Activity Detail

Section 1: Endpoint Summary

Fetch complete activity details for viewing/editing.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /teachers-app/activity/:id
  • Authentication: JWT (Staff)

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "data": {
    "id": "UUID",
    "title": "...",
    "description": "...",
    "activity_type": "event",
    "status": "published"
  }
}

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

TEACH-03: Create Activity

Section 1: Endpoint Summary

Teacher creates new activity (event, announcement, achievement, homework) for school or specific student.

Section 2: HTTP Details

  • HTTP Method: POST
  • Endpoint URL: /teachers-app/activity
  • Authentication: JWT (Staff)

Section 5: Request Body Schema

{
  "title*": "String",
  "description*": "String",
  "activity_type*": "Enum: event, announcement, achievement, homework",
  "status*": "Enum: draft, published",
  "student_id": "UUID (optional, for student-specific)",
  "image_url": "String (optional)"
}

Section 6: Response Schema (Success - 201)

{
  "status": "success",
  "message": "Activity created",
  "data": {
    "id": "UUID",
    "created_at": "2026-03-16T10:00:00.000Z"
  }
}

Section 7: Error Responses

400 - Invalid Type
{
  "status": "error",
  "code": "INVALID_TYPE",
  "message": "activity_type must be event, announcement, achievement, or homework"
}

Section 8: Implementation Examples

JavaScript:
const createActivity = async (token, activity) => {
  const response = await fetch(
    'https://api.skole.com/v1/teachers-app/activity',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(activity)
    }
  );

  const data = await response.json();
  if (data.status === 'success') return data.data.id;
  throw new Error(data.message);
};

// Usage
const activityId = await createActivity(token, {
  title: 'Science Fair 2026',
  description: 'Annual science fair...',
  activity_type: 'event',
  status: 'published'
});

Section 12: Response Summary Table

StatusScenarioError Code
201 ✅Success-
400 ❌InvalidINVALID_TYPE

TEACH-04: Update Activity

Section 1: Endpoint Summary

Teacher updates activity details, status, or description.

Section 2: HTTP Details

  • HTTP Method: PUT
  • Endpoint URL: /teachers-app/activity/:id
  • Authentication: JWT (Staff)

Section 5: Request Body Schema

{
  "title": "String",
  "description": "String",
  "status": "Enum",
  "activity_type": "Enum"
}

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "message": "Activity updated"
}

Section 8: Implementation Examples

JavaScript:
const updateActivity = async (token, activityId, updates) => {
  const response = await fetch(
    `https://api.skole.com/v1/teachers-app/activity/${activityId}`,
    {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(updates)
    }
  );

  return (await response.json()).status === 'success';
};

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

TEACH-05: Delete Activity

Section 1: Endpoint Summary

Teacher soft-deletes activity (hidden from parents, retained for audit).

Section 2: HTTP Details

  • HTTP Method: DELETE
  • Endpoint URL: /teachers-app/activity/:id
  • Authentication: JWT (Staff)

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "message": "Activity deleted"
}

Section 9: Database Context

Sets deleted_status = 1, hides from all consumer APIs

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

ADMIN-01: List All Activities (Web App)

Section 1: Endpoint Summary

Admin views all activities across school with global filters.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /web-app/activity
  • Authentication: JWT (Admin)

Section 4: Query Parameters

ParameterTypeRequiredDescription
activity_typeStringNoFilter by type
created_byUUIDNoFilter by teacher
statusStringNoFilter by status
include_deletedBooleanNoInclude deleted

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "data": {
    "activities": [...],
    "pagination": {
      "total": 150,
      "page": 1
    }
  }
}

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

ADMIN-02: Get Activity Detail (Web App)

Section 1: Endpoint Summary

Admin views complete activity details including creator and engagement stats.

Section 2: HTTP Details

  • HTTP Method: GET
  • Endpoint URL: /web-app/activity/:id
  • Authentication: JWT (Admin)

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

ADMIN-03: Create Activity (Web App)

Section 1: Endpoint Summary

Admin creates activity on behalf of staff (system announcements, corrections).

Section 2: HTTP Details

  • HTTP Method: POST
  • Endpoint URL: /web-app/activity
  • Authentication: JWT (Admin)

Section 5: Request Body Schema

{
  "title*": "String",
  "description*": "String",
  "activity_type*": "Enum",
  "created_by*": "UUID (staff_id)",
  "status": "Enum"
}

Section 6: Response Schema (Success - 201)

{
  "status": "success",
  "message": "Activity created",
  "data": {"id": "UUID"}
}

Section 12: Response Summary Table

StatusScenarioError Code
201 ✅Success-

ADMIN-04: Update Activity (Web App)

Section 1: Endpoint Summary

Admin updates activity details or status.

Section 2: HTTP Details

  • HTTP Method: PUT
  • Endpoint URL: /web-app/activity/:id
  • Authentication: JWT (Admin)

Section 6: Response Schema (Success - 200)

{
  "status": "success",
  "message": "Activity updated"
}

Section 12: Response Summary Table

StatusScenarioError Code
200 ✅Success-

12. Summary Table: All 12 Activity Endpoints

IDEndpointMethodDescriptionStatus
PARENT-01/parent-app/activityGETActivity feed✅ Documented
PARENT-02/parent-app/activity/:idGETActivity detail✅ Documented
PARENT-03/parent-app/activity/categoriesGETList categories✅ Documented
TEACH-01/teachers-app/activityGETList activities✅ Documented
TEACH-02/teachers-app/activity/:idGETActivity detail✅ Documented
TEACH-03/teachers-app/activityPOSTCreate activity✅ Documented
TEACH-04/teachers-app/activity/:idPUTUpdate activity✅ Documented
TEACH-05/teachers-app/activity/:idDELETEDelete activity✅ Documented
ADMIN-01/web-app/activityGETList all✅ Documented
ADMIN-02/web-app/activity/:idGETActivity detail✅ Documented
ADMIN-03/web-app/activityPOSTCreate activity✅ Documented
ADMIN-04/web-app/activity/:idPUTUpdate activity✅ Documented