6 | Contact SupaNuxt SaaS on github 7 |
8 | 9 |We are sorry that you were unable to subscribe.
4 |
5 |
8 |
We are sorry that you canceled your transaction!
4 |
5 |
8 |
22 | 23 | We appreciate your business {{ customer.name }}! 24 | 25 | 26 | It appears your stripe customer information has been deleted! 27 | 28 |
29 |Go to Your
21 | We're sorry to see you go! By clicking the button below, you will initiate 22 | the account deletion process, which will result in the permanent removal 23 | of all your account information stored by SupaNuxt SaaS and associated 24 | service providers. Please be aware that this action is irreversible and 25 | all subscriptions associated with your account will be terminated. Once 26 | your account is deleted, you will lose access to all the features and 27 | benefits of SupaNuxt SaaS. 28 |
29 | 30 |38 | Click below to request to Join the team. Your request to join will 39 | remain as 'Pending' untill the team administrators complete their 40 | review. 41 |
42 |43 | If your requeste is approved, you will become a member of the team and 44 | will be able to switch to the team account at any time in order to 45 | share the benefits of the team plan. 46 |
47 |57 | Only signed in users can join a team. Please either Signup or Signin 58 | and then return to this page using the join link. 59 |
60 | 65 | 66 | 71 | 72 |{{ note.note_text }}
79 | 89 |6 | Your privacy is important to us. This privacy statement explains what 7 | personal data we collect from you and how we use it. By using our website, 8 | you agree to the terms of this privacy statement. 9 |
10 | 11 |14 | We collect personal information that you voluntarily provide to us when 15 | you use our website, including your email and full name. We also collect 16 | non-personal information about your use of our website, such as your IP 17 | address, browser type, and the pages you visit. 18 |
19 | 20 |21 | In addition to the personal data that we collect directly from you, we 22 | also use a third-party authentication provider called Supabase to manage 23 | user authentication. When you use our website, Supabase may collect 24 | personal data about you, such as your email address and authentication 25 | credentials. For more information about Supabase's data practices, please 26 | refer to their privacy policy at 27 | https://supabase.com/privacy. 28 |
29 | 30 |33 | We use your personal information to provide you with the products and 34 | services you request, to communicate with you, and to improve our website. 35 | We may also use your information for marketing purposes, but we will 36 | always give you the option to opt-out of receiving marketing 37 | communications from us. 38 |
39 | 40 |43 | We may disclose your personal information to third parties who provide 44 | services to us, such as website hosting, data analysis, and customer 45 | service. We may also disclose your information if we believe it is 46 | necessary to comply with the law or to protect our rights or the rights of 47 | others. 48 |
49 | 50 |51 | As mentioned above, we use a third-party authentication provider called 52 | Supabase to manage user authentication. Supabase may share your personal 53 | data with other third-party service providers that they use to provide 54 | their services, such as hosting and cloud storage providers. For more 55 | information about Supabase's data sharing practices, please refer to their 56 | privacy policy at 57 | https://supabase.com/privacy. 58 |
59 | 60 |63 | We take reasonable measures to protect your personal information from 64 | unauthorized access, use, or disclosure. However, no data transmission 65 | over the internet or electronic storage is completely secure, so we cannot 66 | guarantee the absolute security of your information. 67 |
68 | 69 |72 | We may update this privacy statement from time to time. Any changes will 73 | be posted on this page, so please check back periodically to review the 74 | most current version of the statement. 75 |
76 | 77 |80 | If you have any questions or concerns about our privacy practices, please 81 | contact us at [insert contact information]. 82 |
83 |or
95 | 103 |or
88 | 96 |
97 | By proceeding, I agree to the
98 |
6 | These terms of service (the "Agreement") govern your use of our website 7 | and services (collectively, the "Service"). By using the Service, you 8 | agree to be bound by the terms of this Agreement. If you do not agree to 9 | these terms, you may not use the Service. 10 |
11 | 12 |15 | You may use the Service only for lawful purposes and in accordance with 16 | this Agreement. You agree not to use the Service: 17 |
18 | 19 |38 | The Service and its entire contents, features, and functionality 39 | (including but not limited to all information, software, text, displays, 40 | images, video, and audio, and the design, selection, and arrangement 41 | thereof) are owned by us, our licensors, or other providers of such 42 | material and are protected by United States and international copyright, 43 | trademark, patent, trade secret, and other intellectual property or 44 | proprietary rights laws. 45 |
46 | 47 |48 | You may not reproduce, distribute, modify, create derivative works of, 49 | publicly display, publicly perform, republish, download, store, or 50 | transmit any of the material on our website, except as follows: 51 |
52 | 53 |72 | The Service is provided on an "as is" and "as available" basis, without 73 | any warranties of any kind, either express or implied, including but not 74 | limited to warranties of merchantability, fitness for a particular 75 | purpose, or non-infringement. We make no warranty that the Service will 76 | meet your requirements, be available on an uninterrupted, secure, or 77 | error-free basis, or be free from viruses or other harmful components. 78 |
79 | 80 |83 | In no event shall we be liable for any direct, indirect, incidental, 84 | special, or consequential damages arising out of or in any way connected 85 | with the use of the Service, whether based on contract, tort, strict 86 | liability, or any other theory of liability. 87 |
88 | 89 |92 | You agree to defend, indemnify, and hold us harmless from and against any 93 | claims, liabilities, damages, judgments, fines, costs, and expenses. 94 |
95 |21 | SupaNuxt SaaS is completely free and open source but you can price your 22 | own SaaS like this 23 |
24 |Single user, 10 notes
32 |33 | $0/mo 34 |
35 | 41 |Single user, 100 notes
48 |49 | $15/mo 50 |
51 | 52 | 53 | 76 | 77 | 83 |10 users, 200 notes
90 |91 | $25/mo 92 |
93 | 94 | 95 | 118 | 119 | 125 |18 | With SupaNuxt SaaS, you can easily get started building your next 19 | web application. Our pre-configured tech stack and industry 20 | leading features make it easy to get up and running in no time. 21 | Look! this guy is working so fast, his hands are just a blur.. you 22 | could be this fast. 23 |
24 |
34 | 52 | The Progressive Vue.js Framework 53 |
54 |59 | Auth including OAuth + Postgresql instance 60 |
61 |Relational Database
68 |73 | Schema management + Strongly typed client 74 |
75 |80 | Server/Client communication with Strong types, SSR compatible 81 |
82 |State Store
87 |92 | Payments including Webhook integration 93 |
94 |101 | A utility-first CSS framework 102 |
103 |108 | The Progressive JavaScript Framework 109 |
110 |115 | AI Completions including Note generation from prompt 116 |
117 |
132 | 136 | SupaNuxt SaaS includes robust user management features, including 137 | authentication with social login (oauth) or email/password, 138 | management of user roles and permissions, and multi-user/team 139 | accounts that permit multiple users to share plan features 140 | including a team administration facility and user roles within 141 | team. This is a great feature for businesses or community groups 142 | who want to share the cost of the plan. 143 |
144 |
153 | 157 | We use Prisma for schema management to make sure you can easily 158 | manage and keep track of your database schema. We also utilise 159 | Prisma based strong types which, with some help from TRPC, 160 | penetrate the entire stack all the way to the web front end. This 161 | ensures that you can move fast with your feature development, 162 | alter schema and have those type changes instantly available and 163 | validated everywhere. 164 |
165 |
174 | 178 | SupaNuxt SaaS includes an approach to config and environment 179 | management that enables customisation and management of api keys. 180 |
181 |
190 | 194 | SupaNuxt SaaS includes multi modal state management that supports 195 | both Single Page Application (SPA) pages such as dashboards and 196 | Server Side Rendered (SSR) style pages for public content that are 197 | crawlable by Search engines like google and facilitate excellent 198 | Search Engine Optimisation (SEO). 199 |
200 |
209 | 213 | SupaNuxt SaaS includes Stripe integration for subscription 214 | payments including Subscription based support for multi pricing 215 | and multiple plans. 216 |
217 |
226 | 230 | SupaNuxt SaaS includes Tailwind integration for site styling 231 | including a themable UI components with daisyUI 232 |
233 |
126 |
127 | ### Walkthrough
128 |
129 | [
](https://www.youtube.com/watch?v=AFfbGuJYRqI)
130 |
131 | ### Tricky Decisions
132 |
133 | _Composition over options API_ - I have decided to use composition api and setup functions accross the board including components, pages and Pinia stores. I was resistant at first, especially with the stores as I was used to Vuex but have come to the conclusion that it is easier to go one approach all over. It's also the latest and greatest and folks don't like to use a starter that starts behind the cutting edge.
134 |
135 | _Prisma over Supabase API_ - I went with Prisma for direct DB access rather than use the Supabase client. This is Primarily to avoid lock-in with Supabase too much. Supabase is great but I thought burdening my users with a future situation where it's difficult to move off it wouldn't be very cool. Also, I really like how Prisma handles schema changes and updates to the client layer and types with just two bash commands, after using other approaches, I find this super smooth.
136 |
137 | _Trpc over REST_ - Primarily for full thickness types without duplication on the client. Also I think the remote procedure call paradigm works well. Note however that I still include a [REST endpoint example](/server/api/note.ts) for flexibility. My preference for mobile is Flutter and there is not a Trpc client for Flutter that i'm aware off so it was important for me to make sure REST works also.
138 |
139 | ## Externals Setup
140 |
141 | Things you gotta do that aren't code (and are therefore not very interesting)
142 |
143 | ### Env
144 |
145 | Copy the [.env_example](/.env_example) file to create [.env](/.env)
146 | Note) This file is for development convenience, is .gitignored by default and should _not_ be added to source control
147 |
148 | ### Supabase
149 |
150 | This solution uses Supabase for Auth and to provide a DB. In addition to Magic Link and email/password login via Supabase, it also supports Google OAuth via Supabase.
151 |
152 | 1. Go to [Supabase](https://supabase.com/) and 'Start your Project'
153 | 2. Setup your org and project (Free tier is fine to start)
154 | 3. Update the project's email template (Supabase -> Authentication -> Email Templates) Note that the default Supabase email templates are very generic and for some reason, this can lead to your emails being sent to spam folders. for e.g. to get my password reset emails to my inbox, I needed to change the subject to "Password Reset for ..." and the email body text.
155 | 4. Choose an OAuth provider. I have chosen Google using these [Instructions](https://supabase.com/docs/guides/auth/social-login/auth-google) for the purposes of demonstration but they all should work.
156 | 5. Go to Project Settings -> API and copy Project URL and Project API Key to SUPABASE_URL and SUPABASE_KEY settings respectively in your [.env](/.env) file
157 | 6. Go to Project Settings -> Database -> Connection String -> URI and copy the uri value into the DATABASE_URL setting in your [.env](/.env) file, remembering to replace `[YOUR-PASSWORD]` with the password you provided when you setup the project.
158 |
159 | ### Stripe
160 |
161 | This solution uses Stripe for Subscription payments.
162 |
163 | 1. Go to [Stripe](https://stripe.com) and setup your business (Free Tier is fine to start)
164 | 2. Create 2 products ('Team Plan' and 'Individual Plan') each with a single price and note the Product ID's and Price ID's
165 | 3. Edit the [seed.ts](/prisma/seed.ts) file and replace the stripe_product_id values with the Product ID's from 2)
166 |
167 | ```typescript
168 | create: {
169 | name: 'Team Plan',
170 | .....
171 | stripe_product_id: '[Your Product ID from Stripe]'
172 | },
173 | ```
174 |
175 | 4. Edit the Pricing [pricing](/pages/pricing.vue) page and put your Price ID's from 2) into the appropriate hidden `price_id` form fields...
176 |
177 | ```html
178 |
179 | ```
180 |
181 | 5. go to the [API Keys](https://dashboard.stripe.com/test/apikeys) page find 'Secret Key' -> reveal test key. click to copy and then replace the STRIPE_SECRET_KEY value in your .env
182 |
183 | 6. install the stripe cli used to forward webhooks (macos)
184 |
185 | ```
186 | brew install stripe/stripe-cli/stripe
187 | ```
188 |
189 | 7. log the CLI into your stripe account.
190 |
191 | ```
192 | stripe login -i
193 | ```
194 |
195 | provide the api key found in step 5) above
196 |
197 | ### Setup Database (Prisma)
198 |
199 | This solution uses Prisma to both manage changes and connect to the Postgresql database provided by Supabase. Your Supabase DB will be empty by default so you need to hydrate the schema and re-generate the local prisma client.
200 |
201 | ```
202 | npx prisma db push
203 | npx prisma generate
204 | npm install @prisma/client --save-dev
205 | npx prisma db seed
206 | ```
207 |
208 | ...you should now have a a Plan table with 3 rows and a bunch of empty tables in your Supabase DB
209 |
210 | ## Developement Setup
211 |
212 | ### Dependencies
213 |
214 | ```bash
215 | # yarn
216 | yarn install
217 |
218 | # npm
219 | npm install
220 |
221 | # pnpm
222 | pnpm install --shamefully-hoist
223 | ```
224 |
225 | ### Webhook Forwarding
226 |
227 | This makes sure that you can debug subscription workflows locally
228 |
229 | ```bash
230 | stripe listen --forward-to localhost:3000/webhook
231 | ```
232 |
233 | If you haven't already done so look at the stripe cli output for this text
234 |
235 | ```
236 | Your webhook signing secret is whsec_xxxxxxxxxxxxx (^C to quit)
237 | ```
238 |
239 | take ths signing secret and update the STRIPE_ENDPOINT_SECRET value in .env
240 |
241 | ### Start the Server
242 |
243 | Start the development server on http://localhost:3000
244 |
245 | ```bash
246 | npm run dev
247 | ```
248 |
249 | ### Running the Tests
250 |
251 | There are a few unit tests, just for the stores because I needed to refactor. Feel free to extend the tests for your use cases, or not, it's your SaaS, not mine.
252 |
253 | ```bash
254 | npm run test
255 | ```
256 |
257 | ## Production
258 |
259 | Build the application for production:
260 |
261 | ```bash
262 | npm run build
263 | ```
264 |
265 | Locally preview production build:
266 |
267 | ```bash
268 | npm run preview
269 | ```
270 |
271 | Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
272 |
273 | ### Going Live on Netlify
274 |
275 | Where you host your SAAS is 100% your problem however :-
276 |
277 | - A quick look at the vue.js discord indicates that netlify has the most mentions (2020) out of all the hosting providers beating out Firebase (1592), Vercel (973) and AWS (740)
278 | - I was able to get my app up and running with ridiculously little effort
279 |
280 | Steps (Assumes your repo is in github)
281 |
282 | 1. Go to [Netlify](https://www.netlify.com/)
283 | 2. Log in with your github account (it's easier) and create an account (Free Tier is fine for now)
284 | 3. Add a New Site -> Import from Existing Proect
285 | 4. Choose your repo (You might need to Configure the Netlify app on GitHub) - Netlify auto-detects a nuxt app pretty good and the defaults it chooses seem to be fine.
286 | 5. Setup environment variables per the .env_example file (SUPABASE_URL, SUPABASE_KEY....etc)
287 | 6. Optionally change site name (e.g. mycoolsaas) or apply a domain name
288 |
289 | 7. Go to [Supabase](https://app.supabase.com/)
290 | 8. Choose your project
291 | 9. Go to URL Authentication -> URL Configuration -> Site URL
292 | 10. enter your new netlify URL e.g. https://mycoolsaas.netlify.app/ and click 'save'
293 | 11. Add the following additional redirect URLs for local development and deployment previews:
294 |
295 | - http://localhost:3000/\*\*
296 | - https://**--mycoolsaas.netlify.app/** (or https://mycustomdomain.com/**)
297 |
298 | 12. If you haven't already done so, edit your Supabase Email templates as the generic ones tend to get blocked by GMail.
299 |
300 | ### Netlify deployments and environment variables
301 |
302 | Netlify is a bit rubbish at updating environment variables so you may need to manually re-deploy your site in certain situations e.g.
303 |
304 | - If on initial load of the site you get a message along the lines of 'SUPABASE_URL is required'.. but you have set that environment variable correctly... try a manual deployment.
305 | - Changing the default domain e.g. setting to a custom domain - If you notice you are redirected to the wrong version of the site after signup to a stripe subscription, this means the URL env variable has not been reset by Netlify. a manual deployment may fix it.
306 |
307 | To manually redeploy to to your Netlify dashboard and navigate to Deploys -> Trigger Deploy -> Deploy site
308 |
--------------------------------------------------------------------------------
/patches/1_4_2-service-refactor-to-namespaces_authcontextremoved.patch:
--------------------------------------------------------------------------------
1 | From 32ac5e68868d66c04cc7918d18e2988b66214519 Mon Sep 17 00:00:00 2001
2 | From: Michael Dausmann