This page is orientation, not legal advice. It describes the shape of the rules well enough for you to build sensibly and to know when the question has outgrown a lesson. If you are storing health data, data about children, or anything you would be uncomfortable seeing in a newspaper, talk to a lawyer in your jurisdiction rather than to a website.
The idea
If your project is run from the EU or serves people in it, the General Data Protection RegulationThe EU law governing what may be done with information about identifiable people. It applies to a one-person project the same way it applies to a company, though the paperwork expected is smaller. applies to anything that can identify a person: a name, an email, an account id, an IP address. The law is long, but the parts a small project runs into are few. Collect only what you need for a stated purpose, say plainly what you collect, keep it no longer than you need it, and delete it when someone asks.
the field test, applied to a signup form
field needed for? keep?
----- ----------- -----
email the login itself yes
name addressing them yes, if you use it
company "might be useful later" no
phone nothing you built yet no
full address unshipped feature no
IP + user agent debugging, 30 days yes, with an expiryHow it works
Data minimisation is one of the principles in Article 5: what you hold must be adequate, relevant, and limited to what is necessary for the purpose you named. Purpose comes first, then the field. A signup form asking for a company name because the form template had one is collecting data with no purpose behind it.
Article 17 gives people the right to have their data erased, and you need a way to do it. For a small project that can be a documented manual procedure rather than a feature: an email address people can write to, and a written sequence of SQL statements you run to remove the rows. Say in your privacy notice what you collect, why, who else sees it (your hosting provider, Stripe, an email service like Resend), and how to ask for deletion. Written honestly, that is one short page.
Two things you should never store yourself. Passwords are stored as a The output of a one-way function. From the hash you cannot recover the original password, so a stolen database does not directly hand over anyone's login., produced by an established algorithm such as bcrypt or argon2, and in practice you get this by using an authentication provider rather than writing it. Card numbers you do not touch at all. Handling them puts you inside PCI DSS, which is why Stripe's checkout collects card details on Stripe's own pages and returns you an identifier.
What to do
- Open your database and list every column that describes a person. For each one, write the purpose it serves in the product today. Drop the columns with no answer, and stop collecting them at the form.
- Write the privacy notice yourself, in plain sentences, listing the real services your data passes through. A generated template that names services you do not use is worse than a short honest page.
- Write the deletion procedure as a file in your repository, with the exact statements to run, and test it once on a throwaway account.
- Set an expiry on the data that ages badly, such as logs and analytics, and delete on that schedule.
Where it breaks
Deletion is harder than it looks, because copies live outside your database: in nightly backups, in your email provider's sent history, in the analytics tool, and in your own exports. You cannot usually rewrite a backup, so the honest position is a documented retention window after which the backups holding that person's row have rolled off. Anonymised data is another common trap, since a record with the name removed but a unique id and a timestamp attached often still identifies one person. And the rules differ by jurisdiction and by data type. This page is a starting posture, not a compliance review.