Package reference
Mirrors the package README (single source). Install @basaltkit/notifications-prisma v1.1.0 — npm · source.
<p align="center"> <a href="https://basaltkit-docs.pages.dev"> <img src="https://basaltkit-docs.pages.dev/social-card.png" alt="Basalt" width="440"> </a> </p>
@basaltkit/notifications-prisma
Prisma-backed implementation of the @basaltkit/notificationsInAppStore — the in-app notification inbox — for production databases (PostgreSQL, MySQL, …).
You bring a generated PrismaClient with the InAppNotification model; the store only touches that delegate. The production counterpart to @basaltkit/notifications-sqlite.
pnpm add @basaltkit/notifications-prisma # peer: @basaltkit/notifications ; you already have @prisma/client1. Add the model
Copy the model from the bundled reference schema (@basaltkit/notifications-prisma/schema.prisma) into your schema.prisma:
model InAppNotification {
id String @id
recipientId String
notification String
title String
body String?
data String?
readAt DateTime?
at DateTime
@@index([recipientId, at])
@@map("in_app_notifications")
}Then prisma migrate dev and prisma generate.
2. Wire the store
import { notificationsPlugin } from '@basaltkit/notifications'
import { prismaInAppStore } from '@basaltkit/notifications-prisma'
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
const n = prismaInAppStore(prisma) // pass your client directly, no cast
createApp({ plugins: [notificationsPlugin({ inApp: n.store, mailer })] })MySQL
The reference schema above is written for PostgreSQL (and works on SQLite), where a bare String is TEXT. On MySQL Prisma makes it VARCHAR(191), and a server outside strict mode truncates a longer value silently — the write succeeds, and the value read back is not the one written. A cut title or body is shown cut, and a cut data is no longer valid JSON.
Copy
schema.mysql.prismainstead (exported as@basaltkit/notifications-prisma/schema.mysql.prisma;basalt prisma:syncpicks it when your datasource ismysql): the free-text columns are widened with native types, the keys stayVARCHAR(191)so they can be indexed.Turn on the guard, so a value that still would not fit is refused (
ColumnLengthError, codeCOLUMN_LENGTH_EXCEEDED, status 422, nothing written) instead of cut:tsprismaInAppStore(prisma, { columnLimits: 'mysql' })'mysql'isnotificationsMysqlColumnLimits— the capacities ofschema.mysql.prisma. A number is a limit in characters (VARCHAR(n)),{ bytes: n }a limit in UTF-8 bytes (theTEXTfamily). Widened a column yourself? Spread the preset and raise it:{ InAppNotification: { ...notificationsMysqlColumnLimits.InAppNotification, notification: 500 } }.Keep MySQL in strict mode (
STRICT_TRANS_TABLES) as well.
Unset (the default), nothing is checked — PostgreSQL and SQLite are unaffected. See the MySQL section of the persistence guide.
Notes
list()returns newest-first, withunreadOnlyandlimit;unreadCount()counts unread.markRead()marks only an existing, still-unread notification (a conditionalupdateManyonreadAt: null), so it's idempotent and reports whether it changed anything.datais stored as JSON text and round-trips unchanged.- For database-per-tenant, route the store through the active tenant's client — see the Database-per-tenant guide.
PrismaNotificationsClienttypes delegate arguments asany(returns stay precise) so a realPrismaClientis assignable and passes directly.
License
MIT