Terms&Condition
sidebar_position: 1
Terms & Conditions Versioning System
Author(s)
- Amarnath Garai
Last Updated Date
2026-05-20
SRS References
- TBD
Version History
| Version | Date | Changes | Author |
|---|---|---|---|
| 1.0 | 2026-05-15 | Initial implementation | Amarnath Garai |
| 1.1 | 2026-05-20 | Updated Terms request and response contracts for semantic versioning | Amarnath Garai |
Feature Overview
Objective:
Provide a complete Terms & Conditions management system with versioning, mandatory acceptance during signup, forced re-acceptance when Terms are updated, and full audit tracking.
Scope:
This feature covers the complete lifecycle of Terms & Conditions management including:
- Versioned Terms & Conditions storage and retrieval
- Mandatory acceptance during user signup
- Forced re-acceptance when Terms are updated
- Admin/System update support
- Full audit tracking of user acceptances
- API-based workflow for frontend integration
Dependencies:
- Database system (PostgreSQL/SQL Server)
- User management system
- Authentication and authorization system
- Audit logging system
Requirements
- User cannot sign up without accepting Terms & Conditions
- Admin/System can create and update Terms & Conditions
- Every update creates a new Terms version using major, minor, and patch version fields
- Users must re-accept updated Terms before accessing system
- Acceptance history is preserved for audit purposes
- System tracks acceptance metadata (IP address, User Agent)
- API endpoints for fetching latest Terms, accepting Terms, and checking status
- Admin endpoints for managing Terms versions and viewing history
- Terms ID and version server-side validation
Design Specifications
-
UI/UX Design:
- Signup page must display latest Terms & Conditions
- Acceptance checkbox required for signup completion
- Login workflow must show Terms acceptance screen if user has outdated version
- Admin dashboard for Terms management and version history
-
Data Models:
Terms & Conditions Table
CREATE TABLE termsandconditions (
id UUID PRIMARY KEY,
majorversion INT NOT NULL,
minorversion INT NOT NULL,
patchversion INT NOT NULL,
versionlabel VARCHAR(50) NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
isactive BOOLEAN NOT NULL DEFAULT TRUE,
createdby UUID NULL,
createdat TIMESTAMPTZ NOT NULL DEFAULT NOW(),
effectivefrom TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT uq_terms_version UNIQUE (majorversion, minorversion, patchversion)
);User Terms Acceptance Table
CREATE TABLE usertermsacceptance (
id UUID PRIMARY KEY,
userid UUID NOT NULL,
termsid UUID NOT NULL,
majorversion INT NOT NULL,
minorversion INT NOT NULL,
patchversion INT NOT NULL,
acceptedat TIMESTAMPTZ NOT NULL DEFAULT NOW(),
ipaddress VARCHAR(100),
useragent TEXT,
CONSTRAINT fkterms
FOREIGN KEY (termsid)
REFERENCES termsandconditions(id)
); -
API Interfaces:
Endpoint Method Parameters Response Response Status Codes /terms/latestGETNone TermsAndConditionsResponse200,500/terms/acceptPOSTtermsId(required, Guid)CommonResponse200,400,401,500/terms/statusGETNone TermsStatusResponse200,401,500/termsPOSTtitle,content,majorVersion,minorVersion,patchVersion,effectiveFromCommonResponse201,400,403,500/terms/historyGETNone List of TermsVersionHistory200,403,500 -
API Examples:
1. Get Latest Terms
GET /terms/latestResponse:
{
"id": "c2f67f3d-0f11-4fd4-a5d2-b0c4d621bc77",
"majorVersion": 1,
"minorVersion": 2,
"patchVersion": 0,
"versionLabel": "1.2.0",
"title": "Terms & Conditions",
"content": "Full terms content...",
"effectiveFrom": "2026-05-15T00:00:00Z"
}C# Response Model
public record TermsAndConditionsResponse
{
public Guid Id { get; init; }
public int MajorVersion { get; init; }
public int MinorVersion { get; init; }
public int PatchVersion { get; init; }
public string VersionLabel { get; init; } = string.Empty;
public string Title { get; init; } = string.Empty;
public string Content { get; init; } = string.Empty;
public DateTime EffectiveFrom { get; init; }
}2. Accept Terms
POST /terms/acceptRequest:
{
"termsId": "c2f67f3d-0f11-4fd4-a5d2-b0c4d621bc77"
}C# Request Model
public record AcceptTermsRequest
{
public Guid TermsId { get; init; }
}Response:
{
"status": 200,
"message": "Terms accepted successfully"
}C# Response Model
public record CommonResponse
{
public int Status { get; init; }
public string? Message { get; init; }
}C# Acceptance Row Model
public record UserAcceptTermsRow
{
public Guid TermsId { get; init; }
public Guid UserId { get; init; }
public int MajorVersion { get; init; }
public int MinorVersion { get; init; }
public int PatchVersion { get; init; }
public string? IpAddress { get; init; }
public string? UserAgent { get; init; }
}3. Check User Terms Status
GET /terms/statusResponse:
{
"isLatestAccepted": false,
"acceptedVersionLabel": "1.1.0",
"latestVersionLabel": "1.2.0",
"requiresAcceptance": true
}C# Response Model
public record TermsStatusResponse
{
public bool IsLatestAccepted { get; init; }
public string? AcceptedVersionLabel { get; init; }
public string LatestVersionLabel { get; init; } = string.Empty;
public bool RequiresAcceptance { get; init; }
}4. Create New Terms Version (Admin)
POST /termsRequest:
{
"title": "Terms & Conditions",
"content": "Updated terms content...",
"majorVersion": 1,
"minorVersion": 2,
"patchVersion": 0,
"effectiveFrom": "2026-05-15T00:00:00Z"
}C# Request Model
public record CreateTermsRequest
{
public string Title { get; init; } = string.Empty;
public string Content { get; init; } = string.Empty;
public int MajorVersion { get; init; }
public int MinorVersion { get; init; }
public int PatchVersion { get; init; }
public DateTime EffectiveFrom { get; init; }
}Response:
{
"status": 201,
"message": "Terms created successfully"
}C# Response Model
public record CommonResponse
{
public int Status { get; init; }
public string? Message { get; init; }
}5. Get Terms Version History (Admin)
GET /terms/historyResponse:
[
{
"majorVersion": 1,
"minorVersion": 0,
"patchVersion": 0,
"versionLabel": "1.0.0",
"createdAt": "2026-01-01T00:00:00Z"
},
{
"majorVersion": 1,
"minorVersion": 1,
"patchVersion": 0,
"versionLabel": "1.1.0",
"createdAt": "2026-03-01T00:00:00Z"
}
] -
Third-Party Integrations:
None -
Workflow:
Signup Workflow
User Opens Signup
↓
Fetch Latest Terms (GET /terms/latest)
↓
Display Terms & Conditions
↓
User Accepts Checkbox
↓
Create User
↓
Store Acceptance Record (POST /terms/accept)
↓
Signup CompleteTerms Update Workflow
Admin/System Updates Terms (POST /terms)
↓
New Terms Version Created
↓
Latest Version Changes
↓
Existing Users Marked as Outdated
↓
Users Must Re-Accept on Next LoginLogin Workflow
User Login
↓
Check Accepted Version (GET /terms/status)
↓
Compare With Latest Version
↓
If Outdated (requiresAcceptance = true)
↓
Force Terms Acceptance Screen
↓
User Accepts Latest Terms ID (POST /terms/accept)
↓
Access Granted
Backend Logic
Get Latest Terms Query
SELECT *
FROM termsandconditions
WHERE isactive = TRUE
ORDER BY majorversion DESC, minorversion DESC, patchversion DESC
LIMIT 1;
Get User Accepted Version Query
SELECT majorversion, minorversion, patchversion
FROM usertermsacceptance
WHERE userid = @UserId
ORDER BY majorversion DESC, minorversion DESC, patchversion DESC
LIMIT 1;
Determine Acceptance Requirement Logic
If Accepted semantic version < Latest semantic version
=> Require Re-Acceptance
Recommended Middleware Logic
During:
- Login
- Token refresh
- App startup
Check:
Has user accepted latest Terms version?
If not:
- Return special error code (HTTP 403)
- Include response code:
TERMS_ACCEPTANCE_REQUIRED - Include latest version label
Example response:
{
"code": "TERMS_ACCEPTANCE_REQUIRED",
"message": "User must accept latest Terms & Conditions",
"latestVersionLabel": "1.2.0"
}
Recommended HTTP Status Codes
| Scenario | Status | Description |
|---|---|---|
| Success | 200 | Request successful |
| Created | 201 | Terms version created |
| Bad Request | 400 | Invalid version or parameters |
| Unauthorized | 401 | User not authenticated |
| Forbidden | 403 | Terms acceptance required |
| Server Error | 500 | Internal error |
Security Considerations
-
Validate Terms Server-Side: Always verify:
- Terms ID exists in database
- Version is active (isactive = TRUE)
- Version is the latest or an allowed accepted version
-
Track Acceptance Metadata:
- Store IP address for audit trail
- Store User Agent for device tracking
- Timestamp all acceptances
-
Enforce Acceptance on Critical Operations:
- Block login if latest Terms not accepted
- Block token refresh if latest Terms not accepted
- Block API access if latest Terms not accepted
-
Audit All Changes:
- Log all Terms creation/updates
- Log all user acceptances
- Maintain immutable acceptance history
-
Prevent Version Manipulation:
- Validate the submitted Terms ID before accepting
- Store the accepted major, minor, and patch version from the database record
- Do not trust frontend-provided version labels or numbers during acceptance