Legal
Privacy policy
Last updated: 16 August 2026. Voorraadscanner · David Geelhoed.
This privacy policy explains which personal data Voorraadscanner processes, why, on what legal basis, for how long, with whom, and what rights you have. It is drafted with regard to the General Data Protection Regulation (GDPR), the Dutch GDPR Implementation Act (UAVG), the Dutch Telecommunications Act (cookies and access to your device), and — where applicable — the Trade Secrets Protection Act and rules on digital services in Book 6 of the Dutch Civil Code.
Voorraadscanner is intended for independent shopkeepers and online sellers. Part of the data in your account is business information. As soon as that data can be traced to a natural person (your email, your name, customer names on pick lists), this policy treats it as personal data.
1. Data controller
Data controller for processing personal data via the Service is David Geelhoed, trading as Daves devs, established in the Netherlands.
David Geelhoed, handelend onder de naam Daves devs · support@voorraadscanner.app.
GDPR requests (access, erasure, objection, data portability) should be sent to support@voorraadscanner.app with the subject “GDPR request”. We will normally respond within one month (art. 12(3) GDPR).
No data protection officer (DPO) has been appointed. That is not required for this Service: there is no large-scale, systematic monitoring and no core activity consisting of processing special categories of personal data (art. 37 GDPR read with UAVG).
Chamber of Commerce number, VAT number, and postal address will be shown here once registered. Until then, support@voorraadscanner.app is the statutory contact point (art. 3:15d Dutch Civil Code). On first request we will send the then-known business details.
2. Which service this concerns
Voorraadscanner is a web application for stock management: products, quantities, barcodes, pick lists, movements, and optionally a connection to your webshop (Shopify or WooCommerce). You scan with your phone via a QR session; you use the dashboard on your PC. You do not need to install an app.
3. Categories of data subjects
- Account users (you, the seller).
- Third parties whose data you place in the Service, for example a customer name or address line in an order reference or pick list. For that data you are generally the data controller yourself; we process it on your instructions as processor (art. 28 GDPR). See Article 12.
- Visitors to login and legal pages (limited technical data).
4. Which data we process
We process only what the Service needs. Below is the full inventory of what the software actually stores or passes on.
4.1 Account and authentication
- Email address (in Auth and in the `users` table).
- If you choose “Continue with Google”: email address and name as provided by Google. We do not store a Google password or save a Google profile photo as a file.
- Password (email login only, stored exclusively as a hash; managed by Supabase Auth).
- Unique user ID (UUID).
- Session tokens in httpOnly cookies (login, session refresh).
- Account creation time and last login, insofar as Auth records them.
4.2 Profile and settings
- Display name (optional) and shop name (optional; e.g. in the sidebar) in the users table.
- Low-stock threshold, scan vibrate preference, default webshop sync for new products.
- Language preference (Dutch or English, as chosen in the app) and currency (EUR).
4.3 Stock and products
- Product name, category, SKU, barcode (EAN/UPC or internal code), quantity, unit price.
- Whether the product syncs to the webshop, external product ID, last sync time.
- Reference to a product photo (`photo_url`): R2 key or an external catalogue URL.
4.4 Product photos
- In the cloud (R2): photos you or the scanner add are compressed to WebP (or JPEG if WebP is not possible) and stored in Cloudflare R2 in the EU. They belong to your account, so you see them on all your computers. Other users cannot see them.
- External catalogue photos (Open Food Facts, UPCitemdb, your webshop) remain a URL at the source; we do not store them as a file unless you take your own photo.
4.5 Orders and pick lists
- Reference (free text field; may contain a customer name if you enter or import it).
- Status (open, picking, completed, cancelled), order lines (product, quantity, picked).
- Source (manual or webshop) and optional external order ID.
- Completed or cancelled pick lists are automatically deleted after 14 days; you can delete them earlier yourself. Open pick lists remain until you complete them, cancel them, or delete your account.
4.6 Stock movements
- Product name, change (+/−), quantity after, reason (manual, scan, pick, import, create, undo, receive, stock count, return), and who booked the movement.
- Optional note when writing off (for example “Damaged”, “Own use”, “Missing”, or free text).
- Time of the movement.
4.7 Webshop connection
- Platform (Shopify, WooCommerce, or custom), store domain, sync direction, whether the connection is active, last sync.
- API keys or tokens you enter (access token, consumer key/secret). These are stored in the Service database. Treat them as trade secrets; rotate them if leaked.
- Product and order data the connection fetches or writes back (stock levels, SKUs, order lines).
4.8 Scan sessions
- Short-lived session ID (QR pairing phone ↔ dashboard), linked to your user ID, with an expiry (default 15 minutes). The phone is not logged in; the session ID is proof that you may scan.
4.9 Barcode lookup (only when you scan an unknown code)
- The barcode is first searched in your own catalogue/webshop.
- If not found: lookup at UPCitemdb (non-food) and/or Open Food Facts.
- Returned name, category, possible photo URL, and price/SKU from your webshop.
4.10 Optional image recognition
Only if the administrator has configured an OpenAI key and you send a photo without a barcode match: the photo goes to OpenAI to estimate a product name/category. Without that key, this does not happen.
4.11 Technical and log data
- IP address, user-agent, time, and requested URL in server and CDN logs (Cloudflare, hosting, Supabase).
- Error messages needed to operate the Service.
- No marketing cookies, no tracking pixels, no profiling for advertising.
4.12 CSV import and barcode labels
- You choose a CSV file on your device. The content is read in the browser and stored as product rows. We do not keep the CSV file itself as a separate object in the cloud; we do keep the imported fields (name, barcode, SKU, quantity, price, etc.).
- Barcode labels are generated in your browser and printed locally or saved as PDF. We do not store a copy of the print file.
4.13 Webhooks from your webshop
If you connect Shopify or WooCommerce, that store may send an “order created” message to our webhook. It may contain order number, lines, SKUs, and — depending on how you configure the store — a customer name or note. We convert that into a pick list in your account. We do not keep the payload as a raw log, only as the fields of that pick list.
4.14 Real-time connection
The dashboard may open a secure websocket (Supabase Realtime) so new scans appear immediately. That connection is tied to your session; no extra personal profile is sent along.
4.15 Demo mode
If the Service runs in demo mode, sample products and orders exist only in your browser memory. That is fictitious data, not real administration, and it does not go to our database.
4.16 Product photos in object storage
Your own product photos are stored in Cloudflare R2, linked to your account. You can replace or delete them in the app. On account deletion we erase the related objects as soon as possible.
4.17 Waitlist for the paid launch
If the 25 founding spots are full, you may voluntarily leave your email address. We keep that address (plus the time of sign-up) to email you once or a few times when Voorraadscanner becomes available to everyone, for payment. That is not an account, not a newsletter, and not marketing about other services. You can request removal via support@voorraadscanner.app.
4.18 Review on the website
Signed-in customers can write one review in the dashboard bar or on their profile (stars, short text, name). We store that, without an email address. The public website only shows 4- or 5-star reviews where you ticked the box. The bar then disappears. Reviews of 1–3 stars stay private. Removal is via support@voorraadscanner.app or by deleting your account.
4.19 Data we do not ask for
- Special categories (art. 9 GDPR): health, race, religion, biometrics for identification, etc. — not intended for this Service.
- Criminal data (art. 10 GDPR / UAVG).
- End-customer payment details (unless you paste them yourself in a free text field; do not do that).
- Location data beyond what your browser needs for the camera (no GPS tracking).
- Dutch citizen service number (BSN). Do not enter a BSN in free fields.
5. Purposes and legal bases (art. 6 GDPR)
| Purpose | Data | Legal basis |
|---|---|---|
| Account, login, session security | Email, password hash or Google identity, cookies, user ID, and name for Google login | Contract (art. 6(1)(b)) and legitimate interest in security (f) |
| Stock, pick lists, movements, labels, CSV | Product and order data, notes | Contract (performance of the Service) |
| Profile (name, shop name) and preferences | Settings | Contract; legitimate interest in a usable interface |
| Product photos in Cloudflare R2 | Image files (WebP or JPEG) | Contract |
| Barcode lookup at third parties | Barcode, possibly product name | Contract; legitimate interest in recognising unknown codes. You start the scan. |
| Optional AI recognition of a photo | Image | Consent / contract for that optional feature, only if the feature is enabled |
| Webshop sync, webhooks, and order import | Tokens, orders, stock, possible customer fields from the store | Contract; you connect voluntarily. For customer data in orders: processing on instructions (art. 28) |
| CSV import and label printing | Product fields; printing happens locally | Contract |
| Notification when paid sign-up opens | Waitlist email address, time of sign-up | Consent (art. 6(1)(a)): you leave the address yourself |
| Review on the public website | The text, stars, and name you enter, plus the time of consent | Consent (art. 6(1)(a)): the tick, and only 4 or 5 stars go live |
| Security, abuse prevention, troubleshooting | Logs, IP, user-agent | Legitimate interest (art. 6(1)(f)); legal obligation where applicable |
| Legal obligations (e.g. DPA request, retention where applicable) | Relevant subset | Legal obligation (art. 6(1)(c)) |
We ask for consent (art. 6(1)(a)) where the Telecommunications Act requires it for non-essential access to your device, and separately for a review on the website. You use the camera yourself; session cookies are strictly necessary. There is no consent banner for tracking, because we do not track.
You may object to legitimate interest (art. 21 GDPR). For processing necessary for the contract (the account itself), you can terminate the Service instead of objecting to core processing.
6. How we obtain data
- Directly from you (forms, scans, CSV, settings).
- Via Google, if you choose “Continue with Google” (email and name).
- Via your device (camera/barcode) and via Cloudflare R2 for product photos.
- Via a webshop you connect (Shopify/WooCommerce), on your instructions.
- Via barcode databases when you scan an unknown code (UPCitemdb, Open Food Facts).
- Automatically from technical communication (logs).
7. Recipients and processors
We do not sell your data. It goes only to parties that technically enable the Service, or to sources you enable yourself.
| Party | Role | Region | Purpose |
|---|---|---|---|
| Supabase (Postgres, Auth, Storage API) | Processor | Frankfurt am Main (eu-central-1), Germany | Account, database, realtime |
| Cloudflare | Processor | EU and possibly other CDN nodes | Hosting/edge of the web app, DDoS, TLS, product photos in R2 (EU) |
| Independent source / third party | United States (and other Google regions) | Only if you sign in with Google: Google sees you use our app and gives us email and name | |
| Open Food Facts | Independent source / third party | EU (France) | Barcode fallback for product name/photo URL |
| UPCitemdb | Independent source / third party | United States | Barcode fallback for non-food |
| OpenAI | Processor / sub-processor (only if configured) | United States | Optional estimate of product name from a photo |
| Shopify or WooCommerce | Your processor / your webshop | According to your contract with them | Only if you enable the connection |
With processors we conclude a data processing agreement where required (art. 28 GDPR). Open Food Facts and UPCitemdb are public or commercial lookup services: your barcode goes there at the moment of search. Their own privacy policies apply to their processing.
8. Transfers outside the EEA
Core data (account, stock, orders) is stored in the EU (Supabase Frankfurt). Transfers outside the EEA may occur for:
- Google (US), if you sign in with Google;
- UPCitemdb (US), if an unknown barcode is looked up there;
- OpenAI (US), only for optional image recognition;
- Cloudflare, insofar as a request hits a node outside the EEA;
- Shopify, depending on your store settings.
Such transfers rely where needed on an adequacy decision, the EU-US Data Privacy Framework, and/or the European Commission's standard contractual clauses (art. 44–49 GDPR), plus appropriate technical measures (TLS).
9. Retention periods
| Data | Period |
|---|---|
| Account, profile, settings, products, open pick lists, movements, connections | While the account exists. After deletion: as soon as possible, except backups and legal duty |
| Completed pick lists | 14 days after completion or cancellation, or earlier if you delete them |
| Password | Hash only, until account deletion or password change |
| Scan session (QR) | Until expiry (default 15 minutes) |
| Product photos (R2 / WebP) | Until you delete the photo or product, or cancel your account |
| Session cookies | Until logout or refresh token expiry |
| Waitlist email (launch) | Until you unsubscribe, until we have sent the notifications and cleared the list, or until 24 months after sign-up — whichever comes first |
| Review (text and public name) | Until you delete the review, withdraw consent, or delete your account. Not public without consent |
| Server/CDN logs | Short cycle, usually days to a few weeks, unless an incident requires longer retention |
| EU database backups | According to the hosting provider's backup policy; then overwritten |
You can have your account and cloud data (including product photos in R2) deleted via support@voorraadscanner.app or via Profile → Delete account. Deleting a photo in the app removes the object in the cloud. Any old local cache you clear via this site's browser data.
10. Security (art. 32 GDPR)
- Access to your rows in the database via row-level security: other users cannot see your stock.
- Passwords hashed by the auth provider; TLS on the connection.
- Phone scanning without login, bounded by a short-lived session ID.
- Product photos in Cloudflare R2, private per account; no public photo bucket.
- Webshop API tokens visible only to your account; keep them secure.
No system is 100% secure. In case of a breach involving personal data, we will — if the law requires — notify the Dutch Data Protection Authority within 72 hours and inform you if there is likely a high risk to your rights (art. 33–34 GDPR).
11. Cookies and access to your device
We place only cookies strictly necessary for login and maintaining your session (Supabase Auth, usually a cookie in the form sb-<project>-auth-token). That is permitted without prior consent under the Telecommunications Act (art. 11.7a), provided information is given — which we do here. Confirmation emails on account creation (if enabled) go via the auth provider's email service. If you choose “Continue with Google”, you are briefly redirected to Google; Google places its own cookies under their policy.
In addition, the browser may keep local cache (including older product photos in IndexedDB). New photos are stored in Cloudflare R2. That is functional storage of the Service, not tracking. The camera is used only when you open the scanner and the browser asks permission; the stream stays on the device until you send a photo or barcode.
We do not use analytics, advertising, or social-media cookies.
12. Your role regarding customer data (processor / controller)
If you place names, addresses, or other data of your webshop customers in pick lists or references, you are data controller for that customer data. Voorraadscanner / David Geelhoed then processes it on your instructions as processor (art. 4(8) and art. 28 GDPR), solely to show the pick list and write off stock. You guarantee that you have a legal basis (usually contract with your customer or legitimate interest in order fulfilment) and that you inform your customers.
The points below form the core of the processor arrangement while you place that customer data in the Service. A separate signed data processing agreement is available on request by email.
- We process that data only on your instruction: delivering the Service, plus what the law requires of us.
- Access is limited to what is needed (you via your account; hosting parties as sub-processors).
- Sub-processors for the core of the Service are listed in Article 7. Material changes to sub-processors we share via this policy or the Service.
- Data remains in the EU in principle (Supabase Frankfurt), except transfers in Article 8 that you enable yourself (barcode, AI, your webshop).
- We take appropriate technical and organisational measures (Article 10).
- In case of a breach affecting your customer data, we inform you without undue delay so you can comply with art. 33–34 GDPR.
- We reasonably assist with access or erasure requests from your customers, insofar as the data is in the Service.
- After end of the Service we erase or anonymise production data according to Article 9, except legal duty and backups that expire automatically.
- On written request and under confidentiality we provide information you reasonably need to verify compliance with art. 28 GDPR.
We do not use that customer data for our own marketing, profiling, or sale to third parties.
12a. Data minimisation, DPIA, and balancing of interests
We ask for no more than the Service needs (art. 5(1)(c) GDPR). No data protection impact assessment (DPIA, art. 35 GDPR) is required: the processing is not large-scale monitoring, not large-scale processing of special data, and not systematic evaluation with legal effects.
Where we use legitimate interest (security, logs, interface preferences), that interest — keeping the Service secure and usable — is weighed against your interest in minimal logging. The intrusion is limited (short retention, no marketing profiling). You may object (art. 21 GDPR).
Your own tax retention obligation (often seven years for administration) rests with you, not us. We do not keep your stock “for the tax authority”; after account deletion the cloud copy disappears according to Article 9. Export in time what you must keep.
13. Automated decision-making
There is no automated decision-making with legal or similarly significant effects (art. 22 GDPR). KPIs (“low stock”) are calculations on your own quantities, not profiling of persons.
14. Minors
The Service is aimed at entrepreneurs. Accounts for children under 16 are not intended. If we notice such an account exists, we may delete it.
15. Your rights
Insofar as the GDPR applies, you have the right to:
- access (art. 15);
- rectification (art. 16);
- erasure (“right to be forgotten”, art. 17), subject to legal exceptions;
- restriction of processing (art. 18);
- data portability (art. 20) of data you provided that we process automatically on the basis of contract or consent — in a commonly used machine-readable format where technically reasonable (for example product export);
- object to processing on legitimate interest (art. 21);
- withdraw consent where that was the basis, without affecting the lawfulness of earlier processing;
- lodge a complaint with the Dutch Data Protection Authority: https://www.autoriteitpersoonsgegevens.nl/.
In the dashboard you can already do much yourself: change profile, delete products and photos, change password, sign out, and delete your entire account plus cloud data (Profile → Delete account). Old local photo cache on other devices you clear yourself via browser data; we delete cloud photos with your account. A waitlist address without an account we remove on request via support@voorraadscanner.app. Email support@voorraadscanner.app if you need help.
We may ask you to verify your identity before fulfilling a GDPR request, to prevent data going to the wrong person.
16. Your obligations as a user
- Do not place others' personal data in free fields if it is not necessary.
- Keep your webshop API keys confidential.
- Clear browser data for this site when selling or sharing a computer, if local cache remains.
- Do not place special-category or criminal personal data in the Service.
17. Changes
This policy may change if the Service or the law changes. The date at the top is leading. For material changes we will try to notify you via the Service or email, insofar as we may use your email for service messages (contract).
18. Governing law
Dutch law applies to this privacy policy, without prejudice to mandatory protection under the GDPR or the law of your place of residence.
See also the Terms of service.