logo logo
Design: Database: MTID-Activity meta

Database MTID-Activity
Purpose Hold member comments and viewing activity for a topic.
Cardinality one MTID-Activity database per member interacting with a topic.
one VisitItem per day member visited the topic.
one ReviewItem per day member reviewed the topic.
one CommentItem per comment posted by the member
Source Code
Items src/ts/dbitems/MTID-Activity.ts
Zod Models
item ActivityItem - union of VisitItem, ReviewItem, CommentItem
item.item one of VisitRecord, ReviewRecord, CommentRecord
VisitItem
itemId 'v${when}' where when is YYMMDD UTC date of visit
item: VisitRecord
    kind 'visit'
    mnum member number of member visiting the topic
    tkey topic key of visited topic
    when date of visit (milliseconds since UTC epoch)
    count count of visits on date
ReviewItem
itemId 'r${when}' where when is YYMMDD UTC date of review
item: ReviewRecord
    kind 'review'
    mnum member number of member reviewing the topic
    tkey topic key of visited topic
    when date of review (milliseconds since UTC epoch)
    count count of reviews on date
CommentItem
itemId 'c${path}' where path is the comment path
item: CommentRecord
    kind 'comment'
    tkey topic key of comment's topic
    mnum member number of member who made the comment
    path list of path components leading to this comment
    when date of comment (milliseconds since UTC epoch)
    what text comments of the comment

Description

The MTID-Activity database is created when a member visits a topic.
It holds many items recording their vists and the comments they make:

  • There is one VisitItem for each day a member visits a topic with a count of the number of times they visited.
  • There is one ReviewItem for each day a member reviews a topic with a count of the number of times they reviewed.
  • There is one CommentItem for each comment a member makes about the topic.
  (see userbase-js/types/index.d.ts)

  export interface Item {              userbase item
    itemId: string                    ╭────────────────────────┐
    item: any ────────────────────┬──▶│ kind: 'visit'          │
    createdBy: Attribution        │   │ when: 1708091838620    │
    updatedBy?: Attribution       │   │ ...                    │
    fileId?: string               │   ╰────────────────────────┘
    fileName?: string             │
    fileSize?: number             │   ╭────────────────────────┐
    fileUploadedBy?: Attribution  ├──▶│ kind: 'review'         │
    writeAccess?: AccessControl   │   │ when: 1708091879727    │
  }                               │   │ ...                    │
                                  │   ╰────────────────────────┘
                                  │
                                  │   ╭────────────────────────┐
                                  └──▶│ kind: 'comment'        │
                                      │ when: 1708091879786    │
                                      │ ...                    │
                                      ╰────────────────────────┘


  ActivityRecord represents the specific type of Item.item for an entry
  in the MTID-Activity database - either VisitRecord, ReviewRecord
  or CommentRecord.

VisitItem

The MTID-Activity database holds one VisitItem for each day the member visits the topic with number of visits on that day and the time of their latest visit.

ReviewItem

The MTID-Activity database holds one ReviewItem for each day the member reviews the topic with number of reviews on that day and the time of their latest review.

CommentItem

The MTID-Activity database holds one CommentItem for each comment the member posts on the topic.

Ownership and Access

Each member in a topic is the owner of their MTID-Activity database.

Each member's MTID-Activity database shared read-only with the other members of the topic.

Zod models

The following Zod models show how the Userbase items are represented in memory.

Note that in addition to the values specified by the Userbase Item interface the kind and database attributes are added during deserialization.

export type ActivityItem =
  | VisitItem
  | ReviewItem
  | CommentItem
;
export const ActivityItem = z.discriminatedUnion('kind', [
  VisitItem,
  ReviewItem,
  CommentItem
]);

VisitItem

export type  VisitItem = z.infer<typeof VisitItem>;
export const VisitItem = z.object({
  kind:                 z.literal('visititem'),
  itemId:               z.string(),
  item:                 VisitRecord,
  updatedBy:            z.custom<Attribution>(),
  database:             z.custom<Database>()
}).strip();
export type  VisitRecord = z.infer<typeof VisitRecord>;
export const VisitRecord = z.object({
  kind:                 z.literal('visit'),
  tkey:                 z.string(),
  mnum:                 z.number(),
  when:                 z.number(),
  count:                z.number(),
}).strip();

ReviewItem

export type  ReviewItem = z.infer<typeof ReviewItem>;
export const ReviewItem = z.object({
  kind:                 z.literal('reviewitem'),
  itemId:               z.string(),
  item:                 ReviewRecord,
  updatedBy:            z.custom<Attribution>(),
  database:             z.custom<Database>()
}).strip();
export type  ReviewRecord = z.infer<typeof ReviewRecord>;
export const ReviewRecord = z.object({
  kind:                 z.literal('review'),
  tkey:                 z.string(),
  mnum:                 z.number(),
  when:                 z.number(),
  count:                z.number(),
}).strip();

CommentItem

export type  CommentItem = z.infer<typeof CommentItem>;
export const CommentItem = z.object({
  kind:                 z.literal('commentitem'),
  itemId:               z.string(),
  item:                 CommentRecord,
  updatedBy:            z.custom<Attribution>(),
  database:             z.custom<Database>()
}).strip();
export type  CommentRecord = z.infer<typeof CommentRecord>;
export const CommentRecord = z.object({
  kind:                 z.literal('comment'),
  tkey:                 z.string(),
  mnum:                 z.number(),
  path:                 z.string(),
  when:                 z.number(),
  what:                 z.string(),
}).strip();