page.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import type { Metadata } from "next";
  2. export const metadata: Metadata = {
  3. title: "Privacy Policy - MovieDice",
  4. description: "MovieDice privacy policy and data handling practices.",
  5. };
  6. export default function PrivacyPage() {
  7. return (
  8. <main className="mx-auto max-w-3xl px-4 py-12">
  9. <h1 className="text-3xl font-bold">Privacy Policy</h1>
  10. <p className="mt-2 text-sm text-foreground/50">Last updated: April 6, 2026</p>
  11. <div className="mt-8 space-y-8 text-foreground/80 leading-relaxed [&_h2]:text-xl [&_h2]:font-semibold [&_h2]:text-foreground [&_h3]:text-base [&_h3]:font-medium [&_h3]:text-foreground [&_ul]:list-disc [&_ul]:pl-5 [&_ul]:space-y-1">
  12. <section>
  13. <h2>1. Controller Identity</h2>
  14. <p className="mt-2">
  15. MovieDice is operated as a self-hosted application by its administrator (the
  16. &quot;Controller&quot;). The Controller is responsible for determining the purposes and
  17. means of processing personal data collected through this application. For data-related
  18. inquiries, contact the site administrator through the channels provided on this site.
  19. </p>
  20. </section>
  21. <section>
  22. <h2>2. Lawful Basis for Processing</h2>
  23. <p className="mt-2">We process personal data under the following lawful bases:</p>
  24. <ul className="mt-2">
  25. <li>
  26. <strong>Legitimate interest:</strong> Processing anonymous identifiers and group
  27. membership data to provide the core movie list and randomizer functionality.
  28. </li>
  29. <li>
  30. <strong>Consent:</strong> Where required by applicable law, your continued use of the
  31. service constitutes consent to the processing described in this policy.
  32. </li>
  33. <li>
  34. <strong>Legal obligation:</strong> We may process data to comply with applicable legal
  35. requirements.
  36. </li>
  37. </ul>
  38. </section>
  39. <section>
  40. <h2>3. Data Inventory and Retention</h2>
  41. <p className="mt-2">We collect and store the following data:</p>
  42. <h3 className="mt-4">Anonymous User Identifier (UUID)</h3>
  43. <p className="mt-1">
  44. A randomly generated unique identifier created via Supabase Anonymous Sign-In. This is
  45. not linked to any email, phone number, or real-world identity. Retained until 12 months
  46. of inactivity, after which the account and all associated data are automatically
  47. deleted.
  48. </p>
  49. <h3 className="mt-4">Display Name</h3>
  50. <p className="mt-1">
  51. A user-chosen name (up to 30 characters) used to identify contributions within a group.
  52. This is not verified and does not need to be a real name. Retained for the lifetime of
  53. the account.
  54. </p>
  55. <h3 className="mt-4">Group Membership</h3>
  56. <p className="mt-1">
  57. Records of which groups a user belongs to and their role (admin or member). Deleted when
  58. a user leaves a group or when the account is deleted.
  59. </p>
  60. <h3 className="mt-4">Movie Preferences</h3>
  61. <p className="mt-1">
  62. Movies added to group lists, including which user added them and watched status. The
  63. association with a specific user is set to null if the user&apos;s account is deleted
  64. (the movie remains on the list). Retained for the lifetime of the group.
  65. </p>
  66. <h3 className="mt-4">Recovery Code</h3>
  67. <p className="mt-1">
  68. A one-time-use 24-character code hashed with Argon2id before storage. The plaintext is
  69. shown once and never stored. The hash is deleted after successful use or account
  70. deletion.
  71. </p>
  72. <h3 className="mt-4">Server Logs</h3>
  73. <p className="mt-1">
  74. Standard HTTP server logs including IP addresses, user agent strings, request paths, and
  75. timestamps. These are used for security monitoring and debugging. Log rotation is
  76. configured with a maximum size of 10MB per file and a maximum of 5 files, resulting in
  77. automatic deletion as logs rotate.
  78. </p>
  79. </section>
  80. <section>
  81. <h2>4. Third-Party Recipients</h2>
  82. <ul className="mt-2">
  83. <li>
  84. <strong>TMDB (The Movie Database):</strong> We send API requests to TMDB to search for
  85. movies and retrieve movie metadata (posters, titles, genres). These requests are made
  86. server-side and do not include your user identifier. TMDB&apos;s privacy policy is
  87. available at{" "}
  88. <a
  89. href="https://www.themoviedb.org/privacy-policy"
  90. target="_blank"
  91. rel="noopener noreferrer"
  92. className="underline hover:text-foreground"
  93. >
  94. themoviedb.org/privacy-policy
  95. </a>
  96. .
  97. </li>
  98. <li>
  99. <strong>Sentry:</strong> We use Sentry for error monitoring. Error reports may include
  100. request metadata but never include user identifiers. UUID path segments are stripped
  101. before transmission. Sentry&apos;s privacy policy is available at{" "}
  102. <a
  103. href="https://sentry.io/privacy/"
  104. target="_blank"
  105. rel="noopener noreferrer"
  106. className="underline hover:text-foreground"
  107. >
  108. sentry.io/privacy
  109. </a>
  110. .
  111. </li>
  112. </ul>
  113. </section>
  114. <section>
  115. <h2>5. International Transfers</h2>
  116. <p className="mt-2">
  117. Error monitoring data sent to Sentry may be processed on servers located in the United
  118. States. Sentry participates in the EU-US Data Privacy Framework. All other data (user
  119. accounts, group data, movie lists) is stored on the self-hosted server and does not
  120. leave the hosting jurisdiction unless explicitly configured otherwise by the
  121. administrator.
  122. </p>
  123. </section>
  124. <section id="gdpr">
  125. <span id="ccpa" className="block -translate-y-4" aria-hidden="true" />
  126. <h2>6. Your Rights</h2>
  127. <p className="mt-2">
  128. Depending on your jurisdiction (including CCPA rights for US/California residents and
  129. GDPR rights for EU/EEA residents), you may have the following rights regarding your
  130. personal data:
  131. </p>
  132. <ul className="mt-2">
  133. <li>
  134. <strong>Right of access:</strong> Request a copy of the data we hold about you.
  135. </li>
  136. <li>
  137. <strong>Right to rectification:</strong> Update your display name at any time within
  138. the app.
  139. </li>
  140. <li>
  141. <strong>Right to erasure:</strong> Delete your account, which removes your user
  142. record, group memberships, and nullifies movie attribution.
  143. </li>
  144. <li>
  145. <strong>Right to restrict processing:</strong> Contact the administrator to request
  146. processing restrictions.
  147. </li>
  148. <li>
  149. <strong>Right to data portability:</strong> Contact the administrator to request your
  150. data in a machine-readable format.
  151. </li>
  152. <li>
  153. <strong>Right to object:</strong> Contact the administrator to object to processing
  154. based on legitimate interest.
  155. </li>
  156. </ul>
  157. <p className="mt-2">
  158. To exercise these rights, contact the site administrator. You may also have the right to
  159. lodge a complaint with your local data protection authority.
  160. </p>
  161. </section>
  162. <section>
  163. <h2>7. Children&apos;s Privacy</h2>
  164. <p className="mt-2">
  165. MovieDice is not intended for use by children under the age of 13. We do not knowingly
  166. collect personal data from children under 13. In the European Economic Area, the service
  167. is not intended for users under the age of 16 without parental consent, in accordance
  168. with the GDPR. If you believe a child has provided data through this service, please
  169. contact the administrator to request its deletion.
  170. </p>
  171. </section>
  172. <section>
  173. <h2>8. Cookies and Local Storage</h2>
  174. <p className="mt-2">MovieDice uses the following browser storage mechanisms:</p>
  175. <ul className="mt-2">
  176. <li>
  177. <strong>Authentication cookies:</strong> HttpOnly, Secure, SameSite=Strict cookies
  178. managed by Supabase for session authentication. These are essential for the service to
  179. function and cannot be disabled.
  180. </li>
  181. <li>
  182. <strong>Admin session cookies:</strong> Encrypted iron-session cookies for admin panel
  183. authentication (8-hour expiry).
  184. </li>
  185. <li>
  186. <strong>IndexedDB:</strong> Used for offline caching of movie list data via TanStack
  187. Query persistence. This data stays on your device and is not transmitted to any
  188. server.
  189. </li>
  190. <li>
  191. <strong>localStorage:</strong> May be used by Supabase client libraries for token
  192. management.
  193. </li>
  194. </ul>
  195. <p className="mt-2">
  196. We do not use any third-party tracking cookies or analytics cookies.
  197. </p>
  198. </section>
  199. <section>
  200. <h2>9. Changes to This Policy</h2>
  201. <p className="mt-2">
  202. We may update this privacy policy from time to time. Changes will be indicated by
  203. updating the &quot;Last updated&quot; date at the top of this page. For significant
  204. changes, we will display a notice within the application. Continued use of the service
  205. after changes constitutes acceptance of the updated policy.
  206. </p>
  207. </section>
  208. </div>
  209. </main>
  210. );
  211. }