PunctuOwlity stores two types of data — users and events. On Android they live in an SQLite database (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/punctuowlity/llms.txt
Use this file to discover all available pages before exploring further.
punctuowlity.db) managed by DatabaseHelper; in the browser they are JSON arrays persisted to localStorage and read back through the getEvents() / getUsers() helpers in app.js.
The events Table / Event Object
Android — SQLite schema
date column stores dates in MM/dd/yyyy format as free-form text. The time column stores the display time string (e.g. 01:30PM or ALL DAY).
Browser — event object shape
In the browser, each event is a plain JavaScript object produced by thenormalizeEvent function in app.js. Every event retrieved via getEvents() is guaranteed to have the following fields:
Unique identifier for the event. For seed events this is a short slug (e.g.
"birthday"). For user-created events it is the string representation of Date.now() at the moment of creation.Human-readable title of the event (e.g.
"Dentist", "Jessica's Wedding").Two-digit day-of-month number, zero-padded (e.g.
"05", "14"). Computed from fullDate by normalizeEvent.ISO 8601 date string in
YYYY-MM-DD format (e.g. "2025-04-14"). This is the canonical date field used for comparisons and notification logic.24-hour time string in
HH:MM format as the user entered it (e.g. "13:30"). Empty string "" indicates an all-day event.Display-formatted time string. Derived from
rawTime by normalizeEvent. A non-empty rawTime is converted to 12-hour format with a two-digit hour (e.g. "01:30PM", "06:30PM"). An empty rawTime produces the literal string "ALL DAY".Abbreviated day-of-week in uppercase, three letters (e.g.
"SAT", "MON", "SUN"). Computed from fullDate via Date.prototype.toLocaleDateString with { weekday: 'short' }.Event category used to filter the tabs on the main events screen. One of:
If a category was explicitly set (e.g. from a saved event), that value is used as-is.
| Value | Meaning |
|---|---|
general | General / uncategorised event (default when no category matches) |
birthday | Auto-detected when the title contains "birthday" |
appointment | Auto-detected when the title contains appointment, dentist, dental, or doctor |
trip | Auto-detected when the title contains trip, travel, or vacation |
Whether the user requested a Web Notification for this event.
true means a notification will fire on the event’s fullDate if Notification.permission === 'granted' and the key has not already been stored in sessionStorage.Event.java model class
The Android Event model lives in com.example.punctuowlityeventtracker.Event. It exposes two constructors and two computed methods:
java.text.SimpleDateFormat with the pattern "MM/dd/yyyy" to parse date, then reformat with "EEE" (for getDayOfWeek) or "dd" (for getDateDay) respectively. getDayOfWeek additionally calls .toUpperCase() on the result.
The users Table / User Object
Android — SQLite schema
UNIQUE constraint on username prevents duplicate registrations at the database level. Passwords are stored as plain text in the current implementation.
Browser — user object shape
In the browser, a user is a plain JavaScript object written tolocalStorage (and mirrored to sessionStorage) under the key punctuowlity-users.
Unique identifier, set to
String(Date.now()) at account creation time.The user’s first name as entered in the
#firstName field on signup.html.The user’s last name as entered in the
#lastName field on signup.html.Email address, stored in lower-case. Accepted as a login credential alongside
username.Optional phone number for SMS alerts. May be an empty string if the user did not provide one.
Username chosen at signup, stored as entered (comparison is case-insensitive). Accepted as a login credential alongside
email.Plain-text password. Compared directly against the value entered in the login form.
DatabaseHelper Methods
DatabaseHelper extends SQLiteOpenHelper and is instantiated with a Context. All methods open the database internally — callers do not manage the connection directly.
insertEvent
Inserts a new row into the events table.
The event title text.
The event date in
MM/dd/yyyy format.The display time string (e.g.
"01:30PM" or "ALL DAY").boolean — true if the insert succeeded (row ID ≠ -1), false otherwise.
updateEvent
Updates an existing row in the events table identified by its integer id.
The primary-key
id of the event to update.Replacement title text.
Replacement date in
MM/dd/yyyy format.Replacement display time string.
boolean — true if at least one row was affected, false otherwise.
deleteEvent
Deletes a single row from the events table.
The primary-key
id of the event to delete.boolean — true if at least one row was deleted, false otherwise.
getAllEvents
Returns every row in the events table as a list of Event objects, in database insertion order.
Returns ArrayList<Event> — an empty list if the table is empty.
getEventById
Looks up a single event by its primary key.
The primary-key
id of the event to retrieve.Event if found, or null if no row with the given id exists.
insertUser
Inserts a new row into the users table. Fails silently (returns false) if username is already taken, because the column carries a UNIQUE constraint.
The chosen username. Must be unique across all stored users.
The plain-text password to store.
boolean — true if the insert succeeded, false if the username is already registered or the insert otherwise failed.
checkUser
Verifies that a (username, password) pair exists in the users table.
The username to check.
The plain-text password to verify.
boolean — true if a matching row exists, false otherwise.
Java usage example
localStorage Keys (Browser)
| Key | Type | Description |
|---|---|---|
punctuowlity-events | JSON array | Array of event objects (see Browser event object shape above). Written by saveEvents(events), read by getEvents(). Initialised to seedEvents the first time getEvents() is called and no saved data is found. |
punctuowlity-users | JSON array | Array of user objects (see Browser user object shape above). Written and read by saveUsers / getUsers, which mirror the value to both localStorage and sessionStorage for resilience. |
punctuowlity-sms | string | Records the user’s SMS / notification choice on sms.html. Either "allowed" or "denied". A null value (key absent) means the user has not yet passed through the SMS permission screen — events.html redirects to sms.html in that case. |
punctuowlity-notified-{id}-{date} | string | Stored in sessionStorage (not localStorage). Keyed by event id and ISO date (e.g. punctuowlity-notified-birthday-2025-04-12). Set to "true" after a Web Notification has been fired for that event on that date, preventing duplicate notifications within the same browser session. |