celest-dev / celest

The Flutter cloud platform
https://celest.dev
Other
232 stars 12 forks source link

Allow Celest environment in the backend #47

Open marcglasberg opened 4 months ago

marcglasberg commented 4 months ago

In a cloud function, if I check celest.currentEnvironment it throws me an error:

An unexpected error occurred: Bad state: Celest has not been initialized. Make sure to call `celest.init()` at the start of your `main` method.

However, it's very useful to know, in the backend code, if it's running locally or not. For example, suppose an admin function that should only work locally (and staging) but not in production. This function can be used to set up the database to some initial state for testing purposes:

Future<void> setDatabase(Portfolio portfolio, Iterable<AvailableStock> availableStocks) async {
   _assertIsNotProduction();
   db.setState(portfolio, availableStocks);
}

/// Some admin functions should NOT work in production.
/// Those that do should make sure it's really the admin who's calling them.
void _assertIsNotProduction() {
   if (celest.currentEnvironment == CelestEnvironment.production)
     throw Exception('This function should only be used in local and staging environments.');
}

Since the celest object is visible from the function code, I think it should have this information (and other information, like the cookies https://github.com/celest-dev/celest/issues/40 maybe). But if you try to access celest.functions from inside a function it should fail with an appropriate error (and not Celest has not been initialized. anyway).

dnys1 commented 4 months ago

Good catch! Let me think about the best way to handle this.

dnys1 commented 4 months ago

Thinking about this some more, I believe there will always need to be a split between the client functionality and the server functionality. Having both available in the same interface will introduce too many footguns.

What would you think about a celestBackend global that is only available on the backend? It would be as close a possible to the frontend's celest global while having divergent functionality where appropriate, for example admin actions, etc.

marcglasberg commented 4 months ago

Yes, you are right. In client.dart:

final celest = Celest();
final celestBackend = CelestBackend();

Only problem is, since it's not possible to make celest only visible in the frontend, and celestBackend only visible in the backend, people will still be able to use them in the wrong place, and then get a runtime error. So I think it's important for the plugin to take care of that, by marking it with an error when you use them in the wrong place. I'll add this to the plugin issue: https://github.com/celest-dev/celest/issues/34.